55

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

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

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

4

13 回答 13

18

<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 测试)

于 2014-09-23T21:17:24.927 回答
13

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

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

/**
 * Binary search for a max value without knowing the exact value, only that it can be under or over
 * It dose not test every number but instead looks for 1,2,4,8,16,32,64,128,96,95 to figure out that
 * you thought about #96 from 0-infinity
 *
 * @example findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)
 * @author Jimmy Wärting
 * @see {@link https://stackoverflow.com/a/35941703/1008999}
 * @param {function} fn       The function to run the test on (should return truthy or falsy values)
 * @param {number}   start=1  Where to start looking from
 * @param {function} _        (private)
 * @returns {number}          Intenger
 */
function findFirstPositive (f,b=1,d=(e,g,c)=>g<e?-1:0<f(c=e+g>>>1)?c==e||0>=f(c-1)?c:d(e,c-1):d(c+1,g)) {
  for (;0>=f(b);b<<=1);return d(b>>>1,b)|0
}

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

console.log(dpi)

于 2016-03-11T13:37:35.357 回答
11

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

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

于 2011-11-21T14:01:33.127 回答
5

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

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

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

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

于 2010-12-17T15:33:34.507 回答
4

@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,而只是一个近似值

于 2016-09-30T15:50:27.837 回答
3
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);
} 

(来自沃达丰)

于 2014-02-05T12:20:42.203 回答
3

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

<img src="image.jpg" style="
    高度:表达式(比例(438、192));
    宽度:表达式(比例(270,192))“ />

函数比例(x,dpi){

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

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

于 2009-11-27T18:06:26.920 回答
2

根据定义,DPI 与显示器的物理尺寸相关。因此,如果不确切了解背后的硬件,您将无法获得真正的 DPI。

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

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

于 2008-11-23T00:31:16.293 回答
1

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

于 2008-11-11T01:49:04.807 回答
0

我刚刚找到了这个链接:http ://dpi.lv/ 。基本上,它是一个用于发现客户端设备分辨率、dpi 和屏幕尺寸的网络工具。

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

于 2014-07-27T20:07:29.430 回答
0

你不能做点别的吗?例如,如果您正在生成要被相机识别的图像(即您运行程序,在相机上滑动手机,奇迹发生了),您不能使用与大小无关的东西吗?

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

于 2008-11-25T21:20:25.820 回答
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;
})();
于 2021-03-21T18:08:56.307 回答
0

生成已知 DPI 列表: https ://stackoverflow.com/a/6793227

检测确切的设备。使用类似的东西:

navigator.userAgent.toLowerCase();

例如检测手机时:

window.isMobile=/iphone|ipod|ipad|android|blackberry|opera mini|opera mobi|skyfire|maemo|windows phone|palm|iemobile|symbian|symbianos|fennec/i.test(navigator.userAgent.toLowerCase());

和利润!

于 2018-05-11T03:03:58.860 回答