问题:当电脑的缩放比不为100%,我们在拷贝图片时,计算坐标点会出现错位
原因:修改缩放比,DPI会改变,我们需要根据系统的缩放比来重新修改坐标
代码如下:
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr ptr);
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(
IntPtr hdc, // handle to DC
int nIndex // index of capability
);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
#region DeviceCaps常量
const int HORZRES = 8;
const int VERTRES = 10;
const int LOGPIXELSX = 88;
const int LOGPIXELSY = 90;
const int DESKTOPVERTRES = 117;
const int DESKTOPHORZRES = 118;
#endregion
/// <summary>
/// 获取宽度缩放百分比
/// </summary>
public static float ScaleX
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
int t = GetDeviceCaps(hdc, DESKTOPHORZRES);
int d = GetDeviceCaps(hdc, HORZRES);
float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
ReleaseDC(IntPtr.Zero, hdc);
ScaleX = (float)Math.Round((double)ScaleX, 2); //这里保留两位小数,避免后面比较时出现错误(1.75缩放比计算出来的有很多位)
return ScaleX;
}
}
private static float GetSystemDPI()
{
float scale = common.ScaleX;
if (scale == 1)
return 96;
else if (scale == 1.25)
return 120;
else if (scale == 1.5)
return 144;
else if (scale == 1.75)
return 168;
else if (scale == 2)
return 192;
else
return 96;
}
//这里获取到DPI后,计算拷贝区域即可
private void ScreenshotForm_Load(object sender, EventArgs e)
{
float dpi = GetSystemDPI();
float rate = dpi / 96;
Bitmap CatchBmp = new Bitmap((int)(Screen.PrimaryScreen.Bounds.Width*rate), (int)(Screen.PrimaryScreen.Bounds.Height*rate), PixelFormat.Format32bppArgb);
CatchBmp.SetResolution(dpi, dpi);
Graphics g = Graphics.FromImage(CatchBmp);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), CatchBmp.Size, CopyPixelOperation.SourceCopy);
g.Dispose();
// 指示窗体的背景图片为屏幕图片
this.BackgroundImage = CatchBmp;
this.BackgroundImageLayout = ImageLayout.Zoom;
this.TopMost = true;
}
计算公式:
[Physical Unit Size]= [独立设备单位尺寸]×[系统DPI]
=1/96 英寸 ×120 dpi
=1.25 象素