为什么 WinForms 将我的图像绘制为 4 倍大小?

Why is WinForms drawing my image 4x the size?

我正在使用 WinForms 创建分辨率为 96dpi 的 512x512 像素图像。初始化后,我使用 OnPaint 使用 Graphics.DrawImage 绘制此图像。当我 运行 该程序时,我得到的是下面显示的图像:本质上是一个 1024x1024 图像,其中包含一些模糊地类似于我想要显示的图像,除了它由 2x2 像素块组成,所有块都具有一致的颜色。这很奇怪。

谁能帮我弄清楚这是怎么回事?这只发生在高 DPI 显示器上,该程序在普通显示器上运行正常。

更新 1: 我使用 SetProcessDpiAwareness(_Process_DPI_Awareness.Process_DPI_Unaware); 显式地将进程设置为不感知 DPI,并在矩形中显式调用 DrawImage,即

e.Graphics.DrawImage(bmp, 
      new Rectangle(0, 0, 512, 512), 
      new Rectangle(0, 0, 512, 512), GraphicsUnit.Pixel);

没有帮助。

编辑 2: 开启 DPI 感知 后,我现在得到了同样的垃圾,但大小合适:

编辑 3: 终于明白了,这些瑕疵是我在 CUDA 端错误渲染的结果。高 DPI 废话只是分散注意力。

This is only happening on high-DPI displays

这是完全正常的,您看到图像被重新缩放以匹配显示器的 DPI。这使得它更大,所以以英寸为单位的尺寸是相同的。

完成此操作的粗略方法是依赖 DPI 虚拟化。 Windows 让您的程序像在 96 DPI 显示器上一样运行,但让它绘制到位图中。并重新缩放该位图以将其显示在屏幕上。相当粗糙,但您的程序仍然可用,文本质量受到明显影响。

不粗暴的方法是当你声明你的程序是dpiAware。现在 Windows 不再有帮助, Graphics.DrawImage() 负责这项工作。它自己重新缩放图像以使图像 DPI 与显示 DPI 相匹配。文字看起来非常清晰。图片,嗯,你得把椅子往后挪一点。

如果您不希望发生这种重新缩放,则必须使用带有 Rectangle 参数的 Graphics.DrawImage() 重载。但请记住,在如此漂亮的显示器上,图像会变成邮票。你得把椅子挪近一点:)