从JS/CSS检测系统DPI/PPI?

48 javascript css mobile dpi ppi

我正在研究一种独特的应用程序,它需要根据显示的设备生成特定分辨率的图像.因此,在常规Windows浏览器(96ppi),iPhone(163ppi),Android G1(180ppi)和其他设备上的输出是不同的.我想知道是否有办法自动检测到这一点.

我最初的研究似乎说不.我看到的唯一建议是在CSS中创建一个宽度指定为"1in"的元素,然后检查它的offsetWidth(另请参阅如何通过javascript访问屏幕显示的DPI设置?).有道理,但iPhone用这种技术骗我,说它是96ppi.

另一种方法可能是以英寸为单位获取显示尺寸,然后除以宽度(以像素为单位),但我不知道如何做到这一点.

Max*_*313 13

<div id='testdiv' style='height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;'></div>
<script type='text/javascript'>
  var devicePixelRatio = window.devicePixelRatio || 1;
  dpi_x = document.getElementById('testdiv').offsetWidth * devicePixelRatio;
  dpi_y = document.getElementById('testdiv').offsetHeight * devicePixelRatio;
  
  console.log(dpi_x, dpi_y);
</script>
Run Code Online (Sandbox Code Playgroud)

从这里抓起来http://www.infobyip.com/detectmonitordpi.php.适用于移动设备!(android 4.2.2测试过)

  • 因为我输入的单词有意义?在所有设备上,css 中的 1in 被定义为 96px,因此在 px 中测量宽度为 1in 的 div 将始终给出 96。然后您只需将它(同样,将始终为 96)乘以 devicePixelRatio,它不是根据标准或限制,它可以是任何东西,特别是任何人都可以用他们想要的任何值覆盖它。总之,这种方法是不可靠的。 (5认同)
  • 您所做的就是将常数 96 乘以 devicePixelRatio(可以覆盖)。这不是获得准确 ppi 的一致方法。 (3认同)

Pau*_*ite 11

resolutionCSS媒体查询 - 它允许您将CSS样式限制为特定的分辨率:

但是,它仅受Firefox 3.5及更高版本,Opera 9及更高版本以及IE 9的支持.其他浏览器根本不会应用特定于分辨率的样式(尽管我没有检查过非桌面浏览器).

  • 这是一个测试它的游乐场http://home.heeere.com/tech-ppi-aware-css-media-query.html (2认同)

End*_*ess 9

我提出了一种根本不需要DOM的方法

DOM可能很乱,要求你在不知道width: x !important样式表中发生了什么东西的情况下将东西附加到身体上.您还必须等待DOM准备好使用...

// Binary search, (faster then loop)
// also don't test every possible value, since it tries low, mid, and high
// http://www.geeksforgeeks.org/find-the-point-where-a-function-becomes-negative/
function findFirstPositive(b, a, i, c) {
  c=(d,e)=>e>=d?(a=d+(e-d)/2,0<b(a)&&(a==d||0>=b(a-1))?a:0>=b(a)?c(a+1,e):c(d,a-1)):-1
  for (i = 1; 0 >= b(i);) i *= 2
  return c(i / 2, i)|0
}


var dpi = findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)

console.log(dpi)
Run Code Online (Sandbox Code Playgroud)

  • 这段代码确实工作得很好,但根本不可读 (3认同)
  • 这始终返回 96,即使在移动设备上也是如此。这成为没有意识到英寸被定义为 96px 的经典错误的受害者。 (2认同)
  • 这是一个更好的版本:https://repl.it/@duzun/findDPIjs#script.js (2认同)

小智 6

这对我有用(但没有在手机上测试):

<body><div id="ppitest" style="width:1in;visible:hidden;padding:0px"></div></body>
Run Code Online (Sandbox Code Playgroud)

然后我放入.js: screenPPI = document.getElementById('ppitest').offsetWidth;

这让我96,这对应于我的系统的ppi.

  • 这不适用于所有设备.我的Android手机报告也是96dpi. (20认同)
  • 不是错误 - "px"不是屏幕像素,它是固定长度0.75 pt,本身是1/72英寸. (9认同)
  • 这似乎不适用于任何设备.一切似乎报告96ppi:http://codepen.io/anon/full/mrfvg (7认同)
  • CSS 规范将 1 px 定义为 1/96 英寸,这就是为什么您的计算将始终返回 96。该英寸不是屏幕上的一英寸,而是考虑到您眼睛的距离,这意味着它在不同的设备。浏览器供应商需要将该因素设置为有意义的值,但情况并非总是如此。 (4认同)

cda*_*uth 5

阅读所有这些回复非常令人沮丧,因为唯一正确的答案是:不,不可能从 JavaScript/CSS 检测 DPI。通常,操作系统本身甚至不知道所连接屏幕的 DPI(并将其报告为 96 dpi,我怀疑这可能是许多人似乎相信他们在 JavaScript 中检测 DPI 的方法是准确的原因)。此外,当多个屏幕连接到形成统一显示的设备时,视口甚至单个 DOM 元素都可以跨越具有不同 DPI 的多个屏幕,这将使这些计算变得非常具有挑战性。

其他答案中描述的大多数方法几乎总是会产生 96 dpi 的输出,即使现在大多数屏幕都有更高的 DPI。例如,根据此计算器,我的 ThinkPad T14 的屏幕有 157 dpi ,但这里描述的所有方法和我的操作系统告诉我它有 96 dpi。

您为 DOM 元素分配 CSS 宽度的想法1in行不通。看起来 CSS 英寸被定义为 96 个 CSS 像素。根据我的理解,CSS 像素被定义为像素乘以devicePixelRatio,传统上是1,但可以更高或更低,具体取决于操作系统图形界面和浏览器中配置的缩放级别。

使用分辨率媒体查询的方法似乎至少在少数设备上产生了一些结果,但它们通常仍然相差超过 2 倍。尽管如此,在大多数设备上,这种方法也会产生 96 dpi 的值。


Fri*_*ure 1

我认为最好的方法是将“嗅探器”图像的建议与设备的已知 DPI 矩阵相结合(通过用户代理和其他方法)。它不会很准确,并且维护起来会很痛苦,但如果不了解更多有关您想要创建的应用程序的信息,这是我可以提供的最佳建议。