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

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

我最初的研究似乎是说不。 我见过的唯一build议是在CSS中创build一个宽度为“1in”的元素,然后检查其偏移量(另请参阅如何通过JavaScript访问屏幕显示的DPI设置? )。 有道理,但iPhone用这种技术对我说谎,说这是96ppi。

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

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

但是, 它只支持Firefox 3.5及以上版本,Opera 9及以上版本和IE 9 。 其他浏览器将不会应用您的解决scheme特定的样式(虽然我没有检查非桌面浏览器)。

 <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; </script> 

从这里抓取http://www.infobyip.com/detectmonitordpi.php 。 适用于移动设备! (android 4.2.2testing)

这是什么对我有用(但没有在手机上testing):

 <body><div id="ppitest" style="width:1in;visible:hidden;padding:0px"></div></body> 

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

这让我96,这对应于我的系统的PPI。

我想出了一种不需要DOM的方法

DOM可能很麻烦,需要你在不知道什么东西正在用width: x !important来追加东西的时候width: x !important在你的样式表中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+(ed)/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) 

我还需要在不同的屏幕dpi下以相同的尺寸显示相同的图像,但仅适用于Windows IE。 我用了:

 <img src =“image.jpg”style =“
    身高:expression(尺度(438,192)); 
     width:expression(scale(270,192))“/>

函数比例(x,dpi){

     // dpi是图像的原始尺寸
    返回x * screen.deviceXDPI / dpi;
 }

在这种情况下,原始图像的宽度/高度是270和438,图像是在192dpi的屏幕上显示的。 screen.deviceXDPI未在Chrome中定义,并且需要更新缩放function才能支持IE以外的浏览器

 function getPPI(){ // create an empty element var div = document.createElement("div"); // give it an absolute size of one inch div.style.width="1in"; // append it to the body var body = document.getElementsByTagName("body")[0]; body.appendChild(div); // read the computed width var ppi = document.defaultView.getComputedStyle(div, null).getPropertyValue('width'); // remove it again body.removeChild(div); // and return the value return parseFloat(ppi); 

}

(来自VodaFone)

@Endless的回复相当不错,但不可读,这是一个类似的固定最小/最大值(这应该是好的)

 var dpi = (function () { for (var i = 56; i < 2000; i++) { if (matchMedia("(max-resolution: " + i + "dpi)").matches === true) { return i; } } return i; })(); 

现在matchMedia得到了很好的支持,并且应该给出好的结果,请参阅http://caniuse.com/#feat=matchmedia

请注意,浏览器不会给你精确的屏幕dpi,但只是一个近似值

我认为你最好的办法是将“嗅探器”图像的build议与已知的DPImatrix(通过用户代理和其他方法)结合起来。 这不是确切的,将是一个痛苦的维护,但不知道更多的应用程序,你试图使这是我可以提供的最好的build议。

DPI被定义为与显示器的物理尺寸相关联。 所以如果不知道背后的硬件,你将无法拥有真正的DPI。

现代操作系统同意一个共同的价值,以便有兼容的显示器:96 dpi。 这是一个耻辱,但这是一个事实。

您将不得不依靠嗅探才能猜测计算分辨率所需的实际屏幕大小(DPI = PixelSize / ScreenSize)。

我刚刚find这个链接: http : //dpi.lv/ 。 基本上它是一个webtool来发现客户端设备的分辨率,dpi和屏幕大小。

我访问了我的电脑和手机,它为我提供了正确的解决scheme和DPI。 有一个github回购,所以你可以看到它是如何工作的。

你不能做别的吗? 例如,如果你正在生成一个图像被相机识别(即你运行你的程序,通过相机刷你的手机,魔术发生),你不能使用大小无关的东西?

如果这是要在受控环境中部署的应用程序,是否可以提供校准实用程序? (你可以做一些简单的打印名片,里面有一个小尺子,在校准过程中使用它)。