Convert Pixels to Inches and vice versa in C#

2019-02-09 17:14发布

I am looking to convert pixes to inches and vice versa. I understand that I need DPI, but I am not sure how to get this information (e.g. I don't have the Graphics object, so that's not an option).

Is there a way?

3条回答
三岁会撩人
2楼-- · 2019-02-09 17:17

There's, physically, no real way without knowing the DPI. Pixels are discrete, inches are not, if you're talking inches on your monitor, you need to know (at the very least) the resolution (and pixel aspect ratio) and the size of the visible monitor area in order to calculate your DPI. The resolution is usually possible to fetch somewhere (I'm not a C# or .NET programmer, so I can't help you there), but the size of the monitor is usually not available. If an estimate is good enough then have the user enter the size of the monitor (i.e. 21" or whatever) and solve for DPI:

(resX/DPI)^2 + (resY/DPI)^2 = screenDiagonal^2

giving (assuming you know the diagonal and the resolution)

DPI = sqrt(resX^2+resY^2)/screenDiagonal

This is just an estimate, as monitors are never exactly 21" (.. or whatever), and the pixel aspect ratio is hardly ever exactly 1:1.

If you're talking inches on paper, then, quite naturally you need to know the DPI of your printer (or, more accurately, the current printer settings).

查看更多
手持菜刀,她持情操
3楼-- · 2019-02-09 17:21

You can create the Graphics object simply by calling this.CreateGraphics() (or more generally Control.CreateGraphics()) and then use the DpiX and DpiY properties as you seem to know. Just remember to dispose the graphics object after creating it (ideally with a Using statement).

If you're not using WinForms, then please let us know what sort of application it is.

查看更多
爷的心禁止访问
4楼-- · 2019-02-09 17:41

On a video device, any answer to this question is typically not very accurate. The easiest example to use to see why this is the case is a projector. The output resolution is, say, 1024x768, but the DPI varies by how far away the screen is from the projector apeture. WPF, for example, always assumes 96 DPI on a video device.

Presuming you still need an answer, regardless of the accuracy, and you don't have a Graphics object, you can create one from the screen with some P/Invoke and get the answer from it.

Single xDpi, yDpi;

IntPtr dc = GetDC(IntPtr.Zero);

using(Graphics g = Graphics.FromHdc(dc))
{
    xDpi = g.DpiX;
    yDpi = g.DpiY;
}

if (ReleaseDC(IntPtr.Zero) != 0)
{
    // GetLastError and handle...
}


[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);    
[DllImport("user32.dll")]
private static extern Int32 ReleaseDC(IntPtr hwnd);
查看更多
登录 后发表回答