C# 在C语言中,将像素转换为英寸,反之亦然#

C# 在C语言中,将像素转换为英寸,反之亦然#,c#,winforms,system.drawing,pixels,inches,C#,Winforms,System.drawing,Pixels,Inches,我希望将像素转换为英寸,反之亦然。我知道我需要DPI,但我不确定如何获取此信息(例如,我没有图形对象,因此这不是一个选项) 有办法吗?如果不了解DPI,就没有实际的办法。像素是离散的,英寸不是,如果你说的是显示器上的英寸,你需要知道(至少)分辨率(和像素纵横比)和可视显示器区域的大小,以便计算你的DPI。分辨率通常可以在某处获取(我不是C#或.NET程序员,因此我无法在这方面帮助您),但显示器的大小通常不可用。如果估计值足够好,则让用户输入显示器的尺寸(即21英寸或任何尺寸),并求解DPI: (

我希望将像素转换为英寸,反之亦然。我知道我需要DPI,但我不确定如何获取此信息(例如,我没有
图形
对象,因此这不是一个选项)


有办法吗?

如果不了解DPI,就没有实际的办法。像素是离散的,英寸不是,如果你说的是显示器上的英寸,你需要知道(至少)分辨率(和像素纵横比)和可视显示器区域的大小,以便计算你的DPI。分辨率通常可以在某处获取(我不是C#或.NET程序员,因此我无法在这方面帮助您),但显示器的大小通常不可用。如果估计值足够好,则让用户输入显示器的尺寸(即21英寸或任何尺寸),并求解DPI:

(resX/DPI)^2 + (resY/DPI)^2 = screenDiagonal^2
给予(假设你知道对角线和分辨率)

这只是一个估计值,因为监视器从来都不是精确的21英寸(…或任何东西),像素纵横比几乎从来都不是精确的1:1


如果你说的是纸上的英寸,那么很自然地,你需要知道打印机的DPI(或者更准确地说,是当前的打印机设置)。

你可以通过调用
this.CreateGraphics()
(或者更一般地说
Control.CreateGraphics()
)来创建图形对象然后使用您似乎知道的DpiX和DpiY属性。只需记住在创建图形对象后处理它(理想情况下使用Using语句)


如果您不使用WinForms,请告诉我们它是什么类型的应用程序。

在视频设备上,对这个问题的任何回答通常都不是很准确。要了解为什么会出现这种情况,最简单的例子是投影仪。例如,输出分辨率为1024x768,但DPI随屏幕与投影仪的距离而变化。例如,WPF在视频设备上始终假定为96 DPI

假设您仍然需要一个答案,无论其准确性如何,并且您没有图形对象,您可以使用一些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);

什么的新闻部?屏幕?打印机我不能。我正在ActiveReports报表的代码隐藏文件中编写代码。它没有这些属性。他说他使用的是WPF,而不是WinForms。同时使用两者会导致严重的头痛。@mmr:不,他没有说他正在使用WPF。事实上,对
图形的引用似乎强烈地暗示了WinForms。无论如何,谢谢你的否决票。既然我没有访问图形对象的权限,我该如何计算DPI?假设其余的都已知,求解DPI方程。我该如何知道显示器的对角线长度?我的应用程序将在我无法控制的计算机上运行。要么你粗略估计一下,假设每个人都有19英寸或21英寸左右;如果这真的很重要,那么你必须问用户,没有人知道(参见投影仪上的答案评论),但在这种情况下,你可能会想使用其他技术来获得更准确的答案。这是一个非常无用的答案。他正在寻找一个系统调用,告诉他windows假设的是DPI(我也是)。根据用户的要求,这应该是公认的答案。
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);