HiDPI显示器下Windows Form截图位置偏移问题求助
HiDPI显示器下WinForms截图位置偏移的解决办法
在HiDPI显示器上,系统会对应用做DPI缩放,WinForms的this.Location返回的是逻辑坐标,但Graphics.CopyFromScreen用的是物理屏幕坐标,两者的缩放比例差直接导致了截图位置偏移。从你的坐标数值来看,819/538≈1.5,184/122≈1.5,说明当前显示器的DPI缩放比例是150%。
解决步骤:
启用应用的DPI感知
这是基础前提,让应用能正确识别显示器的DPI缩放比例,有两种设置方式:- 通过应用清单(app.manifest):找到
<application>节点,添加以下配置:<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings> </application> - 通过代码初始化:在程序入口添加DPI感知设置:
using System.Windows.Forms; using System.Drawing; static class Program { [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool SetProcessDpiAwarenessContext(int dpiFlag); private const int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 3; [STAThread] static void Main() { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new YourForm()); } }
- 通过应用清单(app.manifest):找到
修正截图坐标转换
将窗体的逻辑坐标转换为物理屏幕坐标后再执行截图,修改后的代码如下:// 释放原有Bitmap资源 search?.Dispose(); // 获取窗体左上角的物理屏幕坐标 Point screenPosition = this.PointToScreen(Point.Empty); // 创建对应尺寸的Bitmap(截取客户区用ClientSize,整窗体用Size) search = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); using (Graphics gr = Graphics.FromImage(search)) { // 使用转换后的物理坐标执行截图 gr.CopyFromScreen(screenPosition.X, screenPosition.Y, 0, 0, search.Size); }
PointToScreen(Point.Empty)会自动完成逻辑坐标到物理坐标的转换,不用手动计算缩放比例。如果需要截取包含标题栏和边框的整个窗体,把this.ClientSize换成this.Size即可。
内容的提问来源于stack exchange,提问作者eater Sun
相关产品推荐
相关产品推荐

