Обнаружение системы DPI / PPI из JS / CSS? - PullRequest
47 голосов
/ 11 ноября 2008

Я работаю над своего рода уникальным приложением, которое должно генерировать изображения с определенным разрешением в соответствии с устройством, на котором они отображаются. Таким образом, вывод отличается на обычном браузере Windows (96ppi), iPhone (163ppi), Android G1 (180ppi) и других устройствах. Мне интересно, есть ли способ обнаружить это автоматически.

Кажется, мое первоначальное исследование говорит «нет». Единственное предложение, которое я видел, это сделать элемент, ширина которого в CSS указана как «1 дюйм», а затем проверить его offsetWidth (см. Также Как получить доступ к настройкам DPI экрана на экране через javascript? ). Имеет смысл, но iPhone лжет мне с этой техникой, говоря, что это 96ppi.

Другой подход может заключаться в том, чтобы получить размеры дисплея в дюймах, а затем разделить на ширину в пикселях, но я тоже не уверен, как это сделать.

Ответы [ 12 ]

11 голосов
/ 21 ноября 2011

Существует медиа-запрос resolution CSS - он позволяет ограничить стили CSS до определенных разрешений:

Однако поддерживается только Firefox 3.5 и выше, Opera 9 и выше и IE 9 . Другие браузеры вообще не будут применять ваши стили, специфичные для разрешения (хотя я не проверял браузеры, не относящиеся к рабочему столу).

10 голосов
/ 24 сентября 2014

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

8 голосов
/ 11 марта 2016

Я придумал способ, который не требует 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)
6 голосов
/ 17 декабря 2010

Вот что у меня работает (но не проверял на мобильных телефонах):

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

Затем я вставил .js: screenPPI = document.getElementById('ppitest').offsetWidth;

Это дало мне 96, что соответствует ppi моей системы.

3 голосов
/ 27 ноября 2009

Мне также нужно было отобразить одно и то же изображение с одинаковым размером на разных точках на дюйм, но только для 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, и изображение было разработано на экране с разрешением 192 точек на дюйм. screen.deviceXDPI не определен в Chrome, и необходимо обновить функцию масштабирования для поддержки браузеров, отличных от IE

2 голосов
/ 30 сентября 2016

Ответ от @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

Будьте осторожны, браузер не даст вам точное разрешение экрана, а только приблизительное значение

2 голосов
/ 05 февраля 2014
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)

1 голос
/ 28 июля 2014

Я только что нашел эту ссылку: http://dpi.lv/. По сути, это веб-инструмент для определения разрешения, разрешения и размера экрана клиентского устройства.

Я посетил мой компьютер и мобильный телефон, и он обеспечивает правильное разрешение и DPI для меня. Для этого есть репозиторий github, так что вы можете увидеть, как он работает.

1 голос
/ 23 ноября 2008

DPI по определению привязан к физическому размеру дисплея. Таким образом, вы не сможете получить настоящий DPI, не зная точно аппаратное обеспечение.

Современные ОС согласовали общее значение для обеспечения совместимых дисплеев: 96 точек на дюйм. Это позор, но это факт.

Вам придется полагаться на сниффинг, чтобы угадать реальный размер экрана, необходимый для вычисления разрешения (DPI = PixelSize / ScreenSize).

1 голос
/ 11 ноября 2008

Я думаю, что ваш лучший подход - объединить предложение изображения «сниффер» с матрицей известных DPI для устройств (через пользовательский агент и другие методы). Это не будет точно и будет трудно поддерживать, но не зная больше о приложении, которое вы пытаетесь сделать, это лучшее предложение, которое я могу предложить.

...