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);
}
性能方面,方法四要比方法二快两倍