如何通过JavaScript访问屏幕显示的DPI设置?

59

有没有一种方法可以在JavaScript函数中访问屏幕显示的DPI设置?

我正在尝试在页面上定位HTML面板,当用户的DPI设置为大号(120)时,它会导致位置偏移。我需要知道DPI是多少,以便可以相应地调整位置。

4个回答

45

看起来你可以在IE中使用'screen' DOM对象,它有deviceXDPI、deviceYDPI、logicalXDPI和logicalYDPI属性。

https://www.w3schools.com/jsref/obj_screen.asp

这里有一个来自http://www.webdeveloper.com/forum/showthread.php?t=175278的解决方案(我没有尝试过,似乎是一种完全的hack :) 只需创建一个宽度为1英寸的东西,并以像素为单位测量它!

console.log(document.getElementById("dpi").offsetHeight);
#dpi {
    height: 1in;
    left: -100%;
    position: absolute;
    top: -100%;
    width: 1in;
}
<div id="dpi"></div>


25
这段代码在 http://jsfiddle.net/AvVH4/ 上。对我来说它总是返回 96。 - thugsb
4
这段代码从Windows的显示属性返回“DPI设置”,即96 =“普通大小”,120 =“大号”,或其他自定义设置的值,例如106 =“正常大小的110%”。 - Julien Kronegg
5
似乎没有起作用。在我的iPhone5S上,jsfiddle返回96。 - neoneye
3
无效,请勿尝试。我在我的测试系统上使用了200% DPI设置,无论是IE还是Chrome都没有正确报告它。两者都给了我96。 - c00000fd
3
这是不准确的。在CSS中,“in”单位在屏幕上始终为96像素,无论DPI如何。它只对打印有用。 - Perry
显示剩余5条评论

38

首先,为了避免可能(并且非常普遍)的与DPI(每英寸点数)有关的混淆:

DPI并不完全属于“显示设置”。它在两个不同的上下文中被(误)用:

  1. 一个显示器(或视频)的原生像素每英寸数量。它决定了像素的大小。您可以在14英寸笔记本电脑屏幕和17英寸的液晶监视器上都使用相同的1024x768分辨率。前者大约是1280/14 = 91 DPI,后者大约是1280/17 = 75 DPI。屏幕的DPI是不可变的;无法通过显示设置更改。 更多信息...
  2. 打印时绘制在纸上的每英寸点数。这是印表机/复印机/传真机可以在一英寸纸张上印刷的并排点数。大多数打印机可以设置为以较低的DPI打印,只需将每个点打印为两个、四个等点即可。 更多信息...

在打印图像时,有很多因素会影响图像在纸张上的最终尺寸:

  • 源图像的尺寸——这是像素或数据的数量。
  • 源图像的DPI。该值确定打印图像时应如何解释尺寸。
  • 如果源图像没有嵌入DPI信息(JPEG可以有一个,GIF永远没有),则正在使用的程序可能具有指定DPI的设置。这可以是图片查看器/编辑器甚至是Web浏览器。
  • 通常在打印对话框中指定的缩放系数。
  • 打印机当前的DPI设置。
  • 打印机的物理(最大)DPI。

关键是,你要打印的图像会有效地被重采样(缩小或放大)以匹配最终在打印过程中使用的 DPI。可能会导致这种情况的任何一方(程序、打印驱动程序、打印机)。

现在回到您的问题。不,您无法确定屏幕的 DPI,因为它不在软件领域内。这是一个硬件领域术语,描述用户能够购买多大的监视器。 更新: 我最初在2009年写了这个答案,并理解了当前技术的情况。正如@thure指出的那样,现在你可以(自2012年以来?)使用window.matchMedia函数来确定屏幕的 DPI。

如果您试图实现 HTML 布局的精度,正如其他人建议的那样,您的 CSS 应该使用打印尺寸,例如 em、pt 或 pc,而不是 px。但是,最终结果仍可能取决于所使用的浏览器。如果将您的 HTML 转换为 PDF(或从头生成 PDF)对您来说是一个选项,则打印 PDF 将在屏幕和纸张上给您最真实的 WYSIWYG。


2
虽然您无法更改物理 DPI,但是您可以更改将测量映射到像素的软件,该软件由软件管理,具有任意值,通常通过 EDID 从监视器探测,但可以被覆盖。这就是我认为 OP 想表达的内容。 - Kent Fredric
36
不,有很多情况下,从软件中获取物理属性(如DPI和屏幕尺寸),甚至从Javascript这样的高级别语言中获取,都是有用的。如果API设计者因为无法想出需要这种属性的情况而不暴露这个显而易见的属性,那么他们既缺乏远见,又有全知的妄想。 - Glenn Maynard
1
@Glenn Maynard:是的,事实上,Android在其图形API中支持DIP(设备独立像素)。较低级别的光栅化库会根据屏幕已知的DPI将DIP转换为实际像素。 - Ates Goral
1
@thure 当我写下这个答案的时候,我并不知道有一个名为matchMedia的函数。这个答案可能已经过时了,因此今天可能不太准确。我会更新它以提到这个函数。感谢你提出这个问题。 - Ates Goral
1
更新:虽然 matchMedia 允许查询 dpi,但大多数浏览器将假定显示屏的实际像素密度为 96dpi。 - Will
显示剩余6条评论

35

您可以使用 window.devicePixelRatio 属性来获取屏幕/页面的缩放比例。这在当前桌面(Windows)上的IE、Edge、Chrome和Firefox中都能很好地工作,但它似乎不是一个当前的标准。它在我的传统显示器的桌面PC上返回值为1,在比例为200%的Surface上返回值为2。这些天,值应该在1.0到3.0之间。我可以利用这个属性来校正动态图像服务的大小,以在高分辨率屏幕上提供更清晰的图像。

如果您需要某些逻辑DPI/PPI,请将该值乘以96。虽然它不会是实际物理PPI,但只是操作系统所处理的值。


3
W3规范 该属性返回设备物理像素和设备独立像素的比率。这个值可以用来确定屏幕的分辨率,从而为网页提供更好的显示效果。例如,如果设备像素比率是2,那么每个CSS像素将由4个设备像素绘制。 - Tamlyn
这太棒了。对我有用。 - Tomachi

2
我不知道有什么方法,不过可能有另一种解决方案:
用屏幕相关的度量单位“pt”和“em”来指定你的测量值。

http://www.w3schools.com/cssref/css_units.asp

https://css-tricks.com/the-lengths-of-css/

  • em:
    1em等于当前字体大小。2em表示当前字体大小的两倍。例如,如果一个元素显示为12 pt的字体,则'2em'24 pt。在CSS中,'em'是一个非常有用的单位,因为它可以自动适应读者使用的字体。
  • pt:
    点(1 pt等于1/72英寸
  • pc:
    派卡(1 pc等于12 points

试试这个。 http://www.w3schools.com/cssref/css_units.asp - Sam
9
1pt = 1.33px1pc = 16px。无论dpi如何,由于浏览器假定 1in = 96px,这是不真实和不正确的... 翻译:无论dpi如何,由于浏览器假定 1in = 96px,所以 1pt = 1.33px1pc = 16px,但这种假设是错误的和不真实的。 - Ωmega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接