【问题标题】:What governs DC scaling?控制 DC 缩放的因素是什么?
【发布时间】:2019-05-01 00:20:55
【问题描述】:

此代码的缩放比例取决于我在哪台计算机上运行。

        Metafile image;
        IntPtr dib;
        var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, 1, 1, out dib);
        try
        {
            image = new Metafile(memoryHdc, EmfType.EmfOnly);

            using (var g = Graphics.FromImage(image))
            {
                Render(g, html, left, top, maxWidth, cssData, stylesheetLoad, imageLoad);
            }
        }
        finally
        {
            Win32Utils.ReleaseMemoryHdc(memoryHdc, dib);
        }

进入 Render 方法,Metafile 对象的 PixelFormat 为 DontCare,因此没有有效的垂直或水平分辨率。

从 Render 方法中出来,它的值 Format32bppRgbPhysicalDimension.WidthPhysicalDimension.Height 已增加以适应渲染图像。

如何使缩放独立于本地设置?

这里是CreateMemoryHdc的实现(不是我写的,来自OSS库)。

    public static IntPtr CreateMemoryHdc(IntPtr hdc, int width, int height, out IntPtr dib)
    {
        // Create a memory DC so we can work off-screen
        IntPtr memoryHdc = CreateCompatibleDC(hdc);
        SetBkMode(memoryHdc, 1);

        // Create a device-independent bitmap and select it into our DC
        var info = new BitMapInfo();
        info.biSize = Marshal.SizeOf(info);
        info.biWidth = width;
        info.biHeight = -height;
        info.biPlanes = 1;
        info.biBitCount = 32;
        info.biCompression = 0; // BI_RGB
        IntPtr ppvBits;
        dib = CreateDIBSection(hdc, ref info, 0, out ppvBits, IntPtr.Zero, 0);
        SelectObject(memoryHdc, dib);

        return memoryHdc;
    }

如您所见,传递给 DC 构造函数的宽度、高度和位深度是恒定的。创建元文件会产生不同的物理尺寸。执行此操作后立即

            image = new Metafile(memoryHdc, EmfType.EmfOnly);

元文件的PhysicalDimension.Height(和宽度)在我的工作站上为 26.43,在我正在部署的服务器上为 31.25,因此缩放差异已经很明显,因此可能不是渲染中的任何结果。

这可能是相关的。 BitMapInfo 在 OSS 库中定义,如下所示:

internal struct BitMapInfo
{
    public int biSize;
    public int biWidth;
    public int biHeight;
    public short biPlanes;
    public short biBitCount;
    public int biCompression;
    public int biSizeImage;
    public int biXPelsPerMeter;
    public int biYPelsPerMeter;
    public int biClrUsed;
    public int biClrImportant;
    public byte bmiColors_rgbBlue;
    public byte bmiColors_rgbGreen;
    public byte bmiColors_rgbRed;
    public byte bmiColors_rgbReserved;
}

所以可能设置biXPelsPerMeterbiYPelsPerMeter 会有所帮助。上面的代码没有设置它们并且可能允许平台值。

不幸的是,设置这些值似乎没有任何区别。 msdn 说

biXPelsPerMeter

水平分辨率(以每米像素为单位) 位图的目标设备。应用程序可以使用此值来 从资源组中选择最匹配的位图 当前设备的特性。

所以当加载位图从资源时使用这些设置。这里没有帮助。

这一切看起来都很相关https://www.codeproject.com/articles/177394/%2fArticles%2f177394%2fWorking-with-Metafile-Images-in-NET

知道此代码不在应用程序中运行可能会有所帮助。它将 HTML 呈现为用于打印的元文件,并且它存在于 Web API 网络服务中。

没有用户界面,所以我不知道如何解释它是否是 DPI Aware 的问题。证据表明它受到 DPI 影响,所以这个问题可能是相关的。

【问题讨论】:

  • 您的应用程序是否支持 DPI? link

标签: c# asp.net-web-api gdi wmf


【解决方案1】:

GDI 无法扩展。使用 GDI+ 实现设备独立性。您将失去抗锯齿功能,但无论如何大多数打印设备都是高 DPI。

正在使用的库是否可以选择使用 GDI+?

(在我自己的情况下,是的。问题解决了。)

【讨论】:

    猜你喜欢
    • 2011-05-09
    • 2010-12-30
    • 1970-01-01
    • 2011-07-21
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    相关资源
    最近更新 更多