什么控制 DC 缩放?
What governs DC scaling?
此代码根据我 运行 在哪台计算机上获得不同的缩放比例。
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 方法,它的值为 Format32bppRgb
并且 PhysicalDimension.Width
和 PhysicalDimension.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;
}
所以设置 biXPelsPerMeter
和 biYPelsPerMeter
可能会有帮助。上面的代码没有设置它们并且可能允许平台值。
不幸的是,设置这些值似乎没有任何区别。 msdn 说
biXPelsPerMeter
The horizontal resolution, in pixels-per-meter, of the
target device for the bitmap. An application can use this value to
select a bitmap from a resource group that best matches the
characteristics of the current device.
所以当从资源加载位图时会使用这些设置。这里没有帮助。
了解此代码在应用程序中不 运行 可能会有所帮助。它将 HTML 呈现为用于打印的图元文件,并且存在于 Web API 网络服务中。
没有用户界面,所以我不确定如何解释它是否是 DPI Aware 的问题。证据表明它受到 DPI 影响,所以这个问题可能是相关的。
GDI 不缩放。使用 GDI+ 实现设备独立性。您将失去抗锯齿效果,但无论如何大多数打印设备都是高 DPI。
正在使用的库是否可以选择改用 GDI+?
(在我自己的情况下,是的。问题已解决。)
此代码根据我 运行 在哪台计算机上获得不同的缩放比例。
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 方法,它的值为 Format32bppRgb
并且 PhysicalDimension.Width
和 PhysicalDimension.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;
}
所以设置 biXPelsPerMeter
和 biYPelsPerMeter
可能会有帮助。上面的代码没有设置它们并且可能允许平台值。
不幸的是,设置这些值似乎没有任何区别。 msdn 说
biXPelsPerMeter
The horizontal resolution, in pixels-per-meter, of the target device for the bitmap. An application can use this value to select a bitmap from a resource group that best matches the characteristics of the current device.
所以当从资源加载位图时会使用这些设置。这里没有帮助。
了解此代码在应用程序中不 运行 可能会有所帮助。它将 HTML 呈现为用于打印的图元文件,并且存在于 Web API 网络服务中。
没有用户界面,所以我不确定如何解释它是否是 DPI Aware 的问题。证据表明它受到 DPI 影响,所以这个问题可能是相关的。
GDI 不缩放。使用 GDI+ 实现设备独立性。您将失去抗锯齿效果,但无论如何大多数打印设备都是高 DPI。
正在使用的库是否可以选择改用 GDI+?
(在我自己的情况下,是的。问题已解决。)