問題:當電腦的縮放比不爲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 象素