У меня есть пара растровых изображений / снимков (скриншотов), которые я хотел бы «обернуть» в ЭДС, имеющие определенную ширину c в миллиметрах (и пропорциональную высоту). В идеале я также хотел бы добавить несколько оверлеев (текст и прямоугольники).
Создание и сохранение ЭМП, как правило, работают нормально, но я не могу правильно настроить масштабирование.
Вот мой код:
var sourceBitmap = Image.FromFile(@"C:\temp\example.png");
Metafile metafile;
var aspectRatio = (float)sourceBitmap.Height / (float)sourceBitmap.Width;
var size = new Size(200, (int) (200*aspectRatio));
using (var stream = new MemoryStream())
{
using (var offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))
{
IntPtr deviceContextHandle = offScreenBufferGraphics.GetHdc();
metafile = new Metafile(stream, deviceContextHandle, new RectangleF(0, 0, size.Width, size.Height), MetafileFrameUnit.Millimeter, EmfType.EmfPlusOnly); // this allocates one gdi object
offScreenBufferGraphics.ReleaseHdc();
using (var graphics = Graphics.FromImage(metafile))
{
graphics.PageUnit = GraphicsUnit.Millimeter;
// may need to do something with ScaleTransform here??
var metafileHeader = metafile.GetMetafileHeader();
float sx = metafileHeader.DpiX / graphics.DpiX;
float sy = metafileHeader.DpiY / graphics.DpiY;
graphics.ScaleTransform(sx, sy);
graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), new Rectangle(0, 0, size.Width, size.Height), GraphicsUnit.Pixel);
var pen1 = new Pen(new SolidBrush(Color.Blue));
var pen2 = new Pen(new SolidBrush(Color.Red));
graphics.DrawRectangle(pen1, 0, 0, size.Width, size.Height);
graphics.DrawLine(pen2, 0, 0, size.Width, size.Height);
graphics.DrawLine(pen2, 0, size.Height, size.Width, 0);
graphics.Dispose();
}
}
}
// save as a metafile
IntPtr metafileHandle = metafile.GetHenhmetafile();
var result = Gdi32.CopyEnhMetaFile(metafileHandle, @"C:\temp\example.emf");
if (result.ToInt32() == 0)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
Gdi32.DeleteEnhMetaFile(result);
Gdi32.DeleteEnhMetaFile(metafileHandle);
Ни прямоугольник, ни диагональные линии не верны, а исходное растровое изображение не правильно заполнено в EMF. Что я здесь не так делаю?
Окончательный ЭДС должен быть встроен в документ Word - следовательно, указана c ширина. Обратите внимание, что я не хочу уменьшать размер растровых изображений и включать их напрямую, так как я, вероятно, потеряю качество таким образом. Также обратите внимание, что я не хочу включать в Word полный растровый файл и заставлять его настраивать / масштабировать изображение, так как мне нужно использовать {includepicture}, который, похоже, не работает надежно с масштабированием.