Преобразование пикселей в дюймы и наоборот в C#

Я ищу, чтобы преобразовать пиксы в дюймы и наоборот. Я понимаю, что мне нужен DPI, но я не уверен, как получить эту информацию (например, у меня нет Graphics object, так что это не вариант).

есть ли способ?

3 ответов


на видеоустройстве любой ответ на этот вопрос обычно не очень точен. Самый простой пример, чтобы понять, почему это так, - проектор. Выходное разрешение, скажем, 1024x768, но DPI зависит от того, насколько далеко экран от проектора. Например, WPF всегда предполагает 96 точек на дюйм на видеоустройстве.

предполагая, что вам все еще нужен ответ, независимо от точности, и у вас нет графического объекта, вы можете создать его с экрана с помощью некоторые P/Invoke и получить ответ от него.

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);

физически нет реального способа, не зная DPI. Пиксели дискретны, дюймы нет, если вы говорите дюймы на своем мониторе, вам нужно знать (по крайней мере) разрешение (и соотношение сторон пикселей) и размер видимой области монитора, чтобы рассчитать ваш DPI. Разрешение обычно можно получить где-то (я не программист C# или .NET, поэтому я не могу вам помочь), но размер монитора обычно недоступен. Если оценка достаточно хороша затем пользователь должен ввести размер монитора (т. е. 21" или что-то еще) и решить для DPI:

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

предоставление (при условии, что вы знаете диагональ и разрешение)

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

Это просто оценка, так как мониторы никогда не бывают точно 21" (.. или что угодно), и соотношение сторон пикселей вряд ли когда-либо точно 1:1.

Если вы говорите дюймы на бумаге, то, вполне естественно, вам нужно знать DPI вашего принтера (или, точнее, текущего принтера настроить.)


Вы можете создать графический объект просто позвонив this.CreateGraphics() (или вообще Control.CreateGraphics()), а затем используйте свойства DpiX и DpiY, как вы, кажется, знаете. Просто не забудьте удалить графический объект после его создания (в идеале с помощью оператора Using).

Если вы не используете WinForms, то, пожалуйста, сообщите нам, что это за приложение.