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

时间:2008-11-11 01:19:35

标签: javascript css mobile dpi ppi

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

我最初的研究似乎说不。我见过的唯一建议是在CSS中创建一个宽度指定为“1in”的元素,然后检查它的offsetWidth(另请参阅How to access screen display’s DPI settings via javascript?)。有道理,但iPhone用这种技术骗我,说它是96ppi。

另一种方法可能是以英寸为单位获取显示尺寸,然后除以宽度(以像素为单位),但我不知道该怎么做。

12 个答案:

答案 0 :(得分:11)

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

然而,it’s only supported by Firefox 3.5 and above, Opera 9 and above, and IE 9。其他浏览器根本不会应用特定于分辨率的样式(尽管我没有检查过非桌面浏览器)。

答案 1 :(得分:10)

<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>

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

答案 2 :(得分:8)

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

DOM可能很混乱,要求您在不知道样式表中width: x !important发生了什么的情况下将内容附加到正文中。您还必须等待DOM准备好使用...

&#13;
&#13;
// 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)
&#13;
&#13;
&#13;

答案 3 :(得分:6)

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

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

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

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

答案 4 :(得分:3)

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

<img src="image.jpg" style="
    height:expression(scale(438, 192)); 
    width:expression(scale(270, 192))" />

function scale(x, dpi) {

    // dpi is for orignal dimensions of the image
    return x * screen.deviceXDPI/dpi;
}

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

答案 5 :(得分:2)

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)

答案 6 :(得分:2)

来自@Endless的回复非常好,但根本不可读, 这是一个类似的具有固定最小/最大值的应用程序(它应该是好的)

main

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

请注意,浏览器不会为您提供精确的屏幕dpi,但只能提供近似值

答案 7 :(得分:1)

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

答案 8 :(得分:1)

根据定义,DPI与显示器的物理尺寸相关联。因此,如果不完全了解背后的硬件,您将无法拥有真正的DPI。

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

您必须依赖嗅探才能猜出计算分辨率所需的实际屏幕尺寸(DPI = PixelSize / ScreenSize)。

答案 9 :(得分:1)

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

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

答案 10 :(得分:0)

你不能做别的吗?例如,如果您要生成要由相机识别的图像(即您运行程序,在相机上刷手机,发生魔术),您不能使用与尺寸无关的内容吗?

如果这是要在受控环境中部署的应用程序,您是否可以提供校准实用程序? (你可以制作一些简单的东西,比如带有小尺子的印刷名片,在校准过程中使用它。)

答案 11 :(得分:0)

来自@Endless 回复的可读代码:

const dpi = (function () {
    let i = 1;
    while ( !hasMatch(i) ) i *= 2;

    function getValue(start, end) {
        if (start > end) return -1;
        let average = (start + end) / 2;
        if ( hasMatch(average) ) {
            if ( start == average || !hasMatch(average - 1) ) {
                return average;
            } else {
                return getValue(start, average - 1);
            }
        } else {
            return getValue(average + 1, end);
        }
    }

    function hasMatch(x) {
        return matchMedia(`(max-resolution: ${x}dpi)`).matches;
    }

    return getValue(i / 2, i) | 0;
})();