【问题标题】:Scaling bitmap into EMF via System.Drawing with specific width im millimeters?通过 System.Drawing 以毫米为单位将位图缩放为 EMF?
【发布时间】:2020-08-06 08:52:28
【问题描述】:

我有几个位图/png(屏幕截图),我想将它们“包裹”在具有特定宽度(以毫米为单位)(和成比例的高度)的 EMF 中。理想情况下,我还想添加一些叠加层(文本和矩形)。

创建和保存 EMF 似乎通常可以正常工作,但我无法正确进行任何缩放。

这是我的代码:

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 中。 我在这里做错了什么?

最终的 EMF 应该嵌入到 Word 文档中 - 因此需要特定的宽度。 请注意,我不想缩小位图并直接包含它们,因为这样可能会降低质量。另请注意,我不想在 Word 中包含完整的位图并让它调整/缩放图像,因为我需要使用似乎不能可靠地进行缩放的 {includepicture}。

【问题讨论】:

  • graphics.DrawImage 将遵循 bimap 的 dpi。 - 也许设置 sourceBitmap 的 dpi 会有所帮助。默认情况下,它将是屏幕 dpi,这可能是完全关闭的。使用 Bitmap.SetDpi !

标签: c# system.drawing metafile


【解决方案1】:

我试过你的代码,矩形和对角线是正确的。

更改后(交换参数destRectsrcRect)以下代码

graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), new Rectangle(0, 0, size.Width, size.Height), GraphicsUnit.Pixel);

graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, size.Width, size.Height), new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), GraphicsUnit.Pixel);

源位图正确填充到 EMF 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 2023-03-11
    • 1970-01-01
    • 2015-10-12
    • 2020-09-14
    • 2014-10-12
    • 2018-05-23
    • 1970-01-01
    相关资源
    最近更新 更多