C# DIP坐标转像素px坐标
方法一:
public void TransformToPixels(double unitX, double unitY, out int pixelX, out int pixelY) { using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { pixelX = (int)((g.DpiX / 96) * unitX); pixelY = (int)((g.DpiY / 96) * unitY); } // alternative: // using (Graphics g = Graphics.FromHdc(IntPtr.Zero)) { } }
方法二(WIN32API方式):
[DllImport("gdi32.dll")] public static extern int GetDeviceCaps(IntPtr hDc, int nIndex); [DllImport("user32.dll")] public static extern IntPtr GetDC(IntPtr hWnd); [DllImport("user32.dll")] public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDc); public const int LOGPIXELSX = 88; public const int LOGPIXELSY = 90; public void TransformToPixels(double unitX, double unitY, out int pixelX, out int pixelY) { IntPtr hDc = GetDC(IntPtr.Zero); if (hDc != IntPtr.Zero) { int dpiX = GetDeviceCaps(hDc, LOGPIXELSX); int dpiY = GetDeviceCaps(hDc, LOGPIXELSY); ReleaseDC(IntPtr.Zero, hDc); pixelX = (int)(((double)dpiX / 96) * unitX); pixelY = (int)(((double)dpiY / 96) * unitY); } else throw new ArgumentNullException("Failed to get DC."); }
方法三(不推荐):
读取注册表HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDPI 的DWORD值
方法四(WPF方式):
public void TransformToPixels(Visual visual, double unitX, double unitY, out int pixelX, out int pixelY) { Matrix matrix; var source = PresentationSource.FromVisual(visual); if (source != null) { matrix = source.CompositionTarget.TransformToDevice; } else { using (var src = new HwndSource(new HwndSourceParameters())) { matrix = src.CompositionTarget.TransformToDevice; } } pixelX = (int)(matrix.M11 * unitX); pixelY = (int)(matrix.M22 * unitY); }
性能方面,方法四要比方法二快两倍