[英]How do I determine the true pixel size of my Monitor in .NET?
I want to display an image at 'true size' in my application.我想在我的应用程序中以“真实大小”显示图像。 For that I need to know the pixel size of the display.为此,我需要知道显示器的像素大小。
I know windows display resolution is nominally 96dpi, but for my purposes I want a better guess.我知道 Windows 显示分辨率名义上是 96dpi,但出于我的目的,我想要一个更好的猜测。 I understand this information may not always be available or accurate (eg older CRT displays), but I imagine with the prevelance of LCD displays that this should be possible!我知道这些信息可能并不总是可用或准确(例如旧的 CRT 显示器),但我想随着 LCD 显示器的普及,这应该是可能的!
Is there a way to get the pixel size of my display?有没有办法获得我的显示器的像素大小?
Is there a way to determine if the pixel size is accurate?有没有办法确定像素大小是否准确?
.NET API's preferred (I couldn't find them), but Win32 is OK too, I'm happy to P/Invoke. .NET API 的首选(我找不到它们),但 Win32 也可以,我很高兴 P/Invoke。
For the display size you'll want Screen
.PrimaryScreen.Bounds.Size
(or Screen.GetBounds(myform)
).对于显示器尺寸,你会希望Screen
.PrimaryScreen.Bounds.Size
(或Screen.GetBounds(myform)
)。
If you want the DPI, use the DpiX and DpiY properties of Graphics :如果需要 DPI,请使用Graphics的DpiX和DpiY属性:
PointF dpi = PointF.Empty;
using(Graphics g = this.CreateGraphics()){
dpi.X = g.DpiX;
dpi.Y = g.DpiY;
}
Oh, wait!等一下! You wanted actual, hold a ruler up to the monitor and measure, size?!您想要实际的,将尺子放在显示器上并测量尺寸?! No. Not possible using any OS services.不可以。不能使用任何操作系统服务。 The OS doesn't know the actual dimensions of the monitor, or how the user has it calibrated.操作系统不知道显示器的实际尺寸,也不知道用户如何校准它。 Some of this information is theoretically detectable, but it's not deterministic enough for the OS to use it reliably, so it doesn't.其中一些信息在理论上是可检测的,但它的确定性不足以让操作系统可靠地使用它,所以它没有。
As a work around, you can try a couple of things.作为解决方法,您可以尝试一些方法。
Once you know (or think you know) the monitor's diagonal size, you need to find its physical aspect ratio.一旦您知道(或认为您知道)显示器的对角线尺寸,您就需要找到它的物理纵横比。 Again, a couple of things:再次,有几件事:
Once you know (or think you know) what the monitor's diagonal size and physical aspect ratio are, then you you can calculate it's physical width and height.一旦您知道(或认为您知道)显示器的对角线尺寸和物理纵横比是多少,那么您就可以计算它的物理宽度和高度。 A 2 + B 2 = C 2 , so a few calculations will give it to you good: A 2 + B 2 = C 2 ,所以一些计算会给你带来好处:
If you found out that it's a 17" monitor, and its current resolution is 1280 x 1024:如果您发现它是 17" 显示器,并且其当前分辨率为 1280 x 1024:
1280 2 + 1024 2 = 2686976 1280 2 + 1024 2 = 2686976
Sqrt(2686976) = 1639.1998047828092637409837247032平方(2686976)= 1639.1998047828092637409837247032
17" * 1280 / 1639.2 = 13.274768179599804782820888238165" 17" * 1280 / 1639.2 = 13.274768179599804782820888238165"
17" * 1024 / 1639.2 = 10.619814543679843826256710590532" 17" * 1024 / 1639.2 = 10.619814543679843826256710590532"
This puts the physical width at 13.27" and the physical height at 10.62".这使物理宽度为 13.27",物理高度为 10.62"。 This makes the pixels 13.27" / 1280 = 10.62" / 1024 = 0.01037" or about 0.263 mm.这使得像素为 13.27" / 1280 = 10.62" / 1024 = 0.01037" 或大约 0.263 毫米。
Of course, all of this is invalid if the user doesn't have a suitable resolution, the monitor has wacky non-square pixels, or it's an older analog monitor and the controls aren't adjusted properly for the display to fill the entire physical screen.当然,如果用户没有合适的分辨率,显示器有古怪的非方形像素,或者它是一个较旧的模拟显示器并且控件没有正确调整以使显示器填充整个物理,所有这些都是无效的屏幕。 Or worse, it could be a projector.或者更糟的是,它可能是一台投影仪。
In the end, you may be best off performing a calibration step where you have the user actually hold a ruler up to the screen , and measure the size of something for you.最后,您最好执行校准步骤,让用户实际将尺子举到屏幕上,并为您测量某物的大小。 You could:你可以:
No matter what you do , don't expect your results to be 100% accurate.无论您做什么,都不要期望您的结果是 100% 准确的。 There are way too many factors at play for you (or the user) to get this exactly correct, every time.有太多的因素在起作用,您(或用户)每次都无法完全正确地做到这一点。
Be aware that 96 dpi is usually pretty close to accurate.请注意,96 dpi 通常非常接近准确。 Modern pixels on non-projected screens all tend to be about 0.25 mm, give or take, so you usually end up with about 100 physical pixels per inch, give or take, if the monitor is set to its native resolution.非投影屏幕上的现代像素通常都在 0.25 毫米左右,因此如果显示器设置为其原始分辨率,通常每英寸会有大约100 个物理像素。 (Of course, this is a huge generalization and does not apply to all monitors. Eee PCs, for example, have pixels about 0.19 mm in size, if I remember the specs correctly.) (当然,这是一个巨大的概括,并不适用于所有的显示器。的Eee PC机,例如,具有像素约0.19毫米大小,如果我没有记错的规格。)
sorry, you've got to P/Invoke for this information.抱歉,您必须通过 P/Invoke 获取此信息。
Here's the link that I utilized for it a while ago: http://www.davidthielen.info/programming/2007/05/get_screen_dpi_.html这是我不久前使用的链接: http : //www.davidthielen.info/programming/2007/05/get_screen_dpi_.html
You can check by just manually calculating from your screen size您可以通过从屏幕尺寸手动计算来检查
cos(45)*LCD_SCREEN_DIAGONAL_IN_INCHES/sqrt(HORZ_RES^2 + VERT_RES^2)
That would give you the pixel width in inches这会给你以英寸为单位的像素宽度
GetDeviceCaps
可以被 P/Invoke'd 得到一些数字,但我从来不知道这些数字是值得信赖的......
You may obtain the physical dimensions of the display using the EDID information stored in the registry.您可以使用存储在注册表中的 EDID 信息获取显示器的物理尺寸。 You can obtain the appropriate monitor's registry key using the EnumDisplayDevices windows API call.您可以使用 EnumDisplayDevices Windows API 调用获取相应监视器的注册表项。
WPF's True Size = Pixels * DPI Magnification WPF 的真实尺寸 = 像素 * DPI 放大倍数
DPI Magnification: DPI 放大倍数:
Matrix dpiMagnification
= PresentationSource.FromVisual(MyUserControl).CompositionTarget.TransformToDevice;
double magnificationX = dpiMagnification.M11;
double magnificationY = dpiMagnification.M22;
I had trouble solving this question still in 2020. Back when this question was asked/answered in 2009, .NET C# probably meant Windows Forms.我在 2020 年仍然无法解决这个问题。回到 2009 年提出/回答这个问题时,.NET C# 可能意味着 Windows 窗体。 But WPF
is the de facto standard of the day...但WPF
是当今事实上的标准......
By asking about "true size" you have probably already figured out that the operating system does some calculation with actual pixels (say 1366x768, which I understand is usual laptop resolutions) and the DPI (hard to find) in order to give a control's true size.通过询问“真实大小”,您可能已经发现操作系统会使用实际像素(比如 1366x768,我理解这是通常的笔记本电脑分辨率)和 DPI(很难找到)进行一些计算,以便为控件提供真实的尺寸。 And you are trying to make an app that scales to different monitors.您正在尝试制作一个可扩展到不同显示器的应用程序。
This DPI actual number seems to be hidden, but it has been normalized (converted to a percentage).这个 DPI 实际数字似乎是隐藏的,但它已被标准化(转换为百分比)。 Assume 100% = 96 DPI, just because the actual number does not matter anymore.假设 100% = 96 DPI,只是因为实际数字不再重要。 People can easily increase the system-wide text size by going to Desktop on Windows 10 > right click > Display settings > section Scale and layout > change the percentage to magnify text and other elements.人们可以通过转到 Windows 10 上的桌面 > 右键单击 > 显示设置 > 部分缩放和布局 > 更改百分比以放大文本和其他元素来轻松增加系统范围的文本大小。
You can find the pixels another way, and multiple/divide the pixel by the DPI percentage in order to get true size.您可以通过另一种方式找到像素,并将像素乘以/除以 DPI 百分比以获得真实大小。 For instance, I want to drag a UserControl around a canvas element of a WPF window with the mouse.例如,我想用鼠标在 WPF 窗口的画布元素周围拖动 UserControl。 The user control's pixel count and the mouse xy-coordinates were off by the normalized DPI.用户控件的像素计数和鼠标 xy 坐标被归一化 DPI 关闭。 In order to keep the mouse moving at the same rate as the user control, I use:为了让鼠标以与用户控件相同的速度移动,我使用:
double newXCoord = System.Windows.Forms.Cursor.Position.X;
double newYCoord = System.Windows.Forms.Cursor.Position.Y;
double deltaX = newXCoord - oldXCoord;
double deltaY = newYCoord - oldYCoord;
double magnificationX = 1;
double magnificationY = 1;
Matrix dpiMagnification
= PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice;
if (magnificationMatrix != null)
{
magnificationX = dpiMagnification.M11;
magnificationY = dpiMagnification.M22;
}
PixelsFromLeft += deltaX / m_magnificationX;
PixelsFromTop += deltaY / m_magnificationY;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.