Получение физических размеров экрана / dpi / плотности пикселей в Chrome на Android


88

Вопрос

Есть ли безопасный способ получить действительно правильные физические размеры экрана в Chrome на Android? При необходимости старые версии Chrome и Android можно не рассматривать.

Предыдущие исследования

По stackoverflow есть множество тупиковых вопросов о получении реальных физических размеров экрана устройства из javascript (или css). Кажется, что нет конвергенции между стандартизацией html api и фактическими реализациями браузера в том, что, не говоря уже о реализации браузера, зависит от API ОС, которые, в свою очередь, полагаются на оборудование, предоставляющее правильную информацию.

Между прочим, некоторые предыдущие ответы являются загадочными (год 2011 и тому подобное), предполагая определенную плотность пикселей, которая преобладала в то время, и поэтому бесполезна. Другие относятся к webkit, тогда как Chrome blink мог заменить webkit в chrome (?).

Я хотел бы исследовать существование простого решения, ограничивая работу только Chrome на Android.

Заметка

Это все о решении javascript (или css) внутри браузера, а не о решении для собственного приложения.


21
Это просто неправильно. Мой пользовательский интерфейс хочет знать такие вещи, как размер кнопки, которую видит пользователь. возможно, вы слишком много думаете об этом как разработчик кода;)
matanster

12
Например, размер кнопки не должен составлять процент от области просмотра - он должен быть достаточно большим, чтобы его можно было коснуться. Я не уверен, насколько это имеет смысл для высококачественного дизайна.
Matanster

16
@matt абсолютно правильно. Один из наиболее важных аспектов веб-UX / UI, особенно в мире толстых пальцев, - убедиться, что кнопки подходят для указателя - в данном случае для пальца - а также имеют соответствующий размер для расстояния просмотра. от экрана к глазу. Это новое царство мобильных устройств усложнило дело, поэтому определение физического размера экрана имеет еще большее значение.
Джейсон Т. Фезерингем

7
Я на 100% с тобой @matt. Я не понимаю, почему Mozilla и Google не могут просто предоставить нам свойство JavaScript, подобное тому, window.screenDensityкоторое содержит количество физических пикселей на дюйм устройства, которое вы и я, Мэтт, можем взять оттуда. window.screenHeightи window.screenWidthв физических миллиметрах тоже было бы неплохо.
trusktr

7
@Kinlan В целом важен физический размер экрана. Вот почему в настоящий момент нативная разработка более мощная, чем веб-разработка. В естественной среде я могу сделать кнопку шириной 1 (реальный) дюйм, например, на всех современных устройствах. Насколько мне известно, в настоящее время это невозможно в веб-среде. Я что-то упустил?
trusktr

Ответы:


118

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

Это довольно длинная и сложная история, так что простите меня.

Интернет и все браузеры определяют 1 пиксель как единицу, называемую пикселем CSS. Пиксель CSS - это не настоящий пиксель, а единица измерения, которая считается равной 1/96 дюйма в зависимости от угла обзора устройства. Он указан как опорный пиксель .

Контрольный пиксель - это угол обзора одного пикселя на устройстве с плотностью пикселей 96 точек на дюйм и расстоянием от считывающего устройства на расстоянии вытянутой руки. Таким образом, для номинальной длины руки 28 дюймов угол обзора составляет около 0,0213 градуса. Таким образом, для чтения на расстоянии вытянутой руки 1 пиксель соответствует примерно 0,26 мм (1/96 дюйма).

В 0,26 мм пространства у нас может быть очень много пикселей реального устройства.

Браузер делает это в основном по устаревшим причинам - большинство мониторов с разрешением 96 точек на дюйм, когда зародился Интернет, - но также и для единообразия, в «старые времена» кнопка 22 пикселей на 15-дюймовом экране с разрешением 800x600 была бы вдвое больше, чем кнопка 22 пикселей на 15-дюймовый монитор с разрешением 1600x1200. В этом случае DPI экрана фактически составляет 2x (вдвое больше разрешения по горизонтали, но в том же физическом пространстве). Это плохая ситуация для Интернета и приложений, поэтому большинство операционных систем разработали множество способов абстрагирования значений пикселей в независимые от устройства единицы (DIPS на Android, PT на iOS и CSS Pixel в Интернете ).

Браузер iPhone Safari был первым (насколько мне известно) представил концепцию области просмотра. Это было создано для того, чтобы приложения в стиле рабочего стола отображались на маленьком экране. Область просмотра была определена как ширина 960 пикселей. Это существенно увеличило масштаб страницы в 3 раза (iphone изначально был 320 пикселей), так что 1 пиксель CSS составляет 1/3 физического пикселя. Когда вы определили область просмотра, вы могли заставить это устройство соответствовать 1 пикселю CSS = 1 реальному пикселю при 163dpi.

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

С введением устройств с двойным DPI производители мобильных телефонов не хотели, чтобы мобильные страницы казались меньше на 50%, поэтому они ввели концепцию под названием devicePixelRatio (я полагаю, сначала на мобильном веб-наборе), это позволяет им сохранять 1 пиксель CSS примерно равным 1 /. 96-я часть дюйма, но позвольте вам понять, что ваши активы, такие как изображения, могут быть вдвое больше. Если вы посмотрите на серию iPhone, все их устройства говорят, что ширина экрана в пикселях CSS составляет 320 пикселей, хотя мы знаем, что это неправда.

Поэтому, если вы сделали кнопку размером 22 пикселя в пространстве CSS, изображение на физическом экране будет иметь соотношение пикселей устройства 22 *. На самом деле я говорю это, это не совсем так, потому что соотношение пикселей устройства тоже никогда не бывает точным, производители телефонов устанавливают его на хорошее число, например 2,0, 3,0, а не 2,1329857289918 ....

Таким образом, пиксели CSS не зависят от устройства и позволяют нам не беспокоиться о физических размерах экранов, плотности отображения и т. Д.

Мораль этой истории такова: не беспокойтесь о физическом размере экрана в пикселях. Тебе это не нужно. 50px должен выглядеть примерно одинаково на всех мобильных устройствах, он может немного отличаться, но CSS Pixel - это наш независимый от устройства способ создания согласованных документов и пользовательского интерфейса.

Ресурсы:


1
@matt на планшетах будет так же. Как с книгами Retina Mac. Цель состоит в том, чтобы «CSS-пиксель» был относительно однородным для всех платформ, особенно если вы устанавливаете ширину области просмотра = ширина устройства.
Кинлан

14
Вы сказали: «Вы ничего не можете с ними сделать». Я не согласен. Имея эту информацию, я смогу установить шрифт, который всегда имеет высоту 16 пунктов (16/72 дюйма реального мира). Это бесценно, и это одна из причин, по которой нативная разработка продолжает оставаться более мощной, чем веб-разработка.
trusktr

8
На самом деле, вполне разумное использование реального размера экрана в пикселях - это визуализация фонового изображения с соответствующим разрешением.
WhyNotHugo

2
«50 пикселей должны выглядеть примерно одинаково на всех мобильных устройствах», пожалуйста, докажите это, используя, например, 4-дюймовый телефон 1200x1920 и 10-дюймовый планшет 1000x600 рядом друг с другом.
iloveregex

6
Я также не согласен с тем, что «с ними ничего нельзя сделать»: вы можете надежно определить, является ли устройство телефоном или планшетом, и предположить, что пользователь может легко указать пальцем на верхнюю часть экрана или нет.
Брайан Каннард

11

Основываясь на ответе Мэтта, я провел тест:

// on Macbook Pro Retina (2880x1800, 15.4"), is the calculated diagonal size
// approximately 15.4? Let's see...

var svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var screenWidthMillimeters = svgEl.screenPixelToMillimeterX * 2880;
var screenHeightMillimeters = svgEl.screenPixelToMillimeterY * 1800;
var screenDiagonalMillimeters = Math.sqrt(Math.pow(screenWidthMillimeters, 2) + Math.pow(screenHeightMillimeters, 2)); // pythagorean theorem
var screenDiagonalInches = (screenDiagonalMillimeters / 10 / 2.54); // (mm / 10mm/cm) / 2.54cm/in = in

console.log("The calculated diagonal of the screen is "+screenDiagonalInches+" inches. \nIs that close to the actual 15.4\"?");

Это результат:

The calculated diagonal of the screen is 35.37742738560738 inches. 
Is that close to the actual value of 15.4?

Неа.

Так что, похоже, пока нет способа получить реальные физические значения в веб-браузере.


Я не уверен, о каком ответе вы говорите (я нигде не вижу "Мэтт"), но я получаю NaN из-за того, что, по- svgEl.screenPixelToMillimeterXвидимому, не определен.
Майкл

6

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

<div id="meter" style="width:10cm"></div>

А затем получите его ширину в пикселях. Например, HTML-код ниже (я использовал JQuery) показывает ширину экрана устройства в сантиметрах.

<script>
var pixPer10CM = $('#meter').width();
var CMPerPix = 10 / pixPer10CM;
var widthCM = screen.width * CMPerPix;

alert(widthCM);
</script>

Вау, я никогда не думал, что вы можете сделать это с помощью css. Насколько это точно? Как ваш браузер узнает физические размеры вашего экрана? Совместимость браузера для этого где-нибудь на caniuse.com ? Я не могу его найти.
Джейк Уилсон,

4
На сайте W3C говорится: «В прошлом CSS требовал, чтобы реализации правильно отображали абсолютные единицы измерения даже на экранах компьютеров. Но поскольку количество неправильных реализаций превысило количество правильных, и ситуация, похоже, не улучшилась, CSS отказался от этого требования в 2011 году. В настоящее время , абсолютные единицы должны корректно работать только при выводе на печать и на устройствах с высоким разрешением. CSS не определяет, что означает «высокое разрешение». Но поскольку в настоящее время принтеры низкого уровня имеют разрешение 300 точек на дюйм, а экраны высокого класса - 200 точек на дюйм, отсечка, вероятно, где-то посередине ".
Майк

1
Я думаю, что браузер, как и любое другое собственное приложение, может получать разрешение устройства через API ОС, предоставляемый ОС драйвером устройства. От этой информации зависит точность.
Майк

Но разрешение устройства не совпадает с реальными физическими размерами. Ноутбук с диагональю 14 дюймов и ноутбук с диагональю 15 дюймов могут иметь одинаковое разрешение.
Джейк Уилсон

6
Нет! Вы не можете. 10 см в CSS будут иметь другой размер в реальности. Если у него действительно будет 10 см, 12 см или 7 см, это просто вопрос удачи. Вот моя демонстрация jsfiddle, основанная на этом решении, возвращающая неправильные значения, поскольку браузеры всегда ведут себя так, как будто у них есть пиксели на дюйм (dpi): jsfiddle.net/Lzsm3zo9
Дариуш Сикорский

5

Вы можете получить эту информацию с помощью WURFL:

Свойства отображения устройства

Атрибуты называются:

resolution_(width|height)

physical_display_(width|height)

Длинная версия:

Лучшая и наиболее надежная стратегия для достижения этого - отправить user agent stringиз браузера в БД, подобную WURFL(или другую) обновленную БД, которая может предоставить необходимую информацию.

Строка пользовательского агента

Это часть информации, которую могут предоставить все современные браузеры; он предоставляет информацию об устройстве и его ОС. Это просто не имеет смысла для вашего приложения без помощи словаря, например WURFL.

WURFL

Это база данных, обычно используемая для определения свойств устройства.

С его помощью вы сможете точно поддерживать большинство популярных устройств на рынке. Я бы разместил демонстрацию кода, но ее можно загрузить с WURFLсайта. Вы можете найти такую ​​демонстрацию в папке examples / demo, загружаемой вместе с библиотекой.

Скачать WURFL

Вот дополнительная информация и объяснения о проверке физического размера и разрешения: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286


3

В дополнение к ответу «У этой проблемы нет хорошего решения» просто проверьте единицы, которые вы можете использовать в CSS https://www.w3schools.com/cssref/css_units.asp

Unit    Description
cm      centimeters
mm      millimeters
in      inches (1in = 96px = 2.54cm)
px *    pixels (1px = 1/96th of 1in)
pt      points (1pt = 1/72 of 1in)
pc      picas (1pc = 12 pt)

* Pixels (px) are relative to the viewing device.
For low-dpi devices, 1px is one device pixel (dot) of the display.
For printers and high resolution screens 1px implies multiple device pixels.

С этим описанием, кажется, есть решение. cm, mmи inбудет использоваться для рисования чего-то одного и того же размера независимо от размера и разрешения экрана. Имея это в виду, вы можете ожидать , что по крайней мере один из px, ptили pcмогут быть использованы для рисования на уровне пикселей, для любой точности вы хотели бы использовать ( в противном случае, какой смысл на том , миллионы пикселей, верно?). Ну нет. Все единицы являются долями метрической единицы, что делает все эти единицы просто разными шкалами. И хуже всего в этой истории то, что все это не соответствует действительности. Просто поиграйте с примером w3schools (нарисуйте линию 20 см и измерьте ее линейкой).

Так , в конце концов: - нет никакого способа , чтобы сделать что - то с физическими размерами точно (что должно быть в случае с cm, mm, inи в конце концов ptи pc). - нет возможности нарисовать что-то одного и того же размера независимо от размера и разрешения экрана (что должно иметь место по крайней мере px).

Это как проблема реализации (фактический размер экрана не используется), так и проблема дизайна (почему не должно pxзависеть от размера экрана, когда для этого уже существует так много единиц).


2

Я решил эту проблему в одном из моих веб-проектов http://www.vinodiscover.com Ответ заключается в том, что вы не можете точно знать, каков физический размер, но вы можете получить приблизительное значение. Используя JS и / или CSS, вы можете определить ширину и высоту области просмотра / экрана, а также плотность пикселей с помощью медиа-запросов. Например: iPhone 5 (326 пикселей на дюйм) = 320 пикселей на 568 пикселей и плотность пикселей 2,0, а Samsung Galaxy S4 (441 пикселей на дюйм) = 360 пикселей на 640 пикселей и плотность пикселей 3,0. Фактически плотность 1,0 пикселя составляет около 150 пикселей на дюйм.

Учитывая это, я установил в своем CSS отображение 1 столбца при ширине менее 284 пикселей, независимо от плотности пикселей; затем два столбца от 284 пикселей до 568 пикселей; затем 3 столбца выше 852 пикселей. Это намного проще, чем кажется, поскольку теперь браузеры автоматически вычисляют плотность пикселей.

http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html


3
В нативной разработке вы можете получить точное значение. +1 для нативного, -1 для Интернета.
trusktr

Можете ли вы получить точный физический размер в Android?
Аполло Кларк


2

В ответ на ответ zehelvion об использовании WURFL для поиска разрешения также стоит упомянуть, что WURFL также доступен в виде фрагмента кода JavaScript .

В бесплатной версии, предлагаемой на wurfl.io , вы не получите информацию об экране и разрешении (только название устройства, форм-фактор и мобильный / не мобильный), но здесь также есть коммерческая версия с дополнительными возможностями .


3
Я предлагаю сделать это в комментариях к этому конкретному ответу.
darkgaze

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

2

CSS-пиксели на самом деле не являются нашим «пикселем, независимым от устройства». Веб-платформа состоит из множества типов устройств. Хотя CSS-пиксель выглядит довольно стабильно на портативных устройствах, он будет на 50% больше на обычном настольном мониторе с разрешением 96 точек на дюйм. См. Мой вопрос . В некоторых случаях это действительно неплохо, например, на большом экране шрифты должны быть больше, так как расстояние до глаза больше. Но размеры элементов пользовательского интерфейса должны быть довольно согласованными. Допустим, у вашего приложения есть верхняя панель, вы бы предпочли, чтобы она была одинаковой толщины на настольных компьютерах и мобильных устройствах, по умолчанию она будет на 50% меньше, что не очень хорошо, потому что сенсорные элементы должны быть больше. Единственный обходной путь, который я нашел, - это применить разные стили на основе DPI устройства.

Вы можете получить разрешение экрана в JavaScript с помощью window.devicePixelRatio. Или запрос CSS:

@media  only screen and (-webkit-min-device-pixel-ratio: 1.3),
    only screen and (-o-min-device-pixel-ratio: 13/10),
    only screen and (min-resolution: 120dpi)
    {
     /* specific styles for handhelds/ high dpi monitors*/
    }

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


нет, не можешь. медиа-запросы делают эту дурацкую чушь "предположим 96 точек на дюйм", т.е. они лгут вам о том, что такое прочитанное DPI.
Майкл

1

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

У меня была такая же проблема, пока я не обнаружил, что это просто вопрос добавления метатега в заголовок HTML, чтобы установить начальный масштаб:

<meta name="viewport" content="width=device-width, initial-scale=1">


0

JqueryMobile ширина элемента

$(window).width();   // returns width of browser viewport
$(document).width(); // returns width of HTML document

JqueryMobile Высота элемента

$(window).height();   // returns height of browser viewport
$(document).height(); // returns height of HTML document

Удачи, Дэнни117


3
Это виртуальные измерения, которые не всегда являются физическими измерениями реального мира.
trusktr

Спасибо, я этого не знал
danny117 01

0

Используя функцию getPPI () ( Мобильный Интернет: как получить физический размер в пикселях? ), Чтобы получить идентификатор в один дюйм, используйте эту формулу:

var ppi = getPPI();
var x   = ppi * devicePixelRatio * screen.pixelDepth / 24;
$('#Cubo').width (x);
$('#Cubo').height(x);

<div id="Cubo" style="background-color:red;"></div>

5
почему pixelDepth ?! не имеет отношения pixelDepth к глубине цвета, и в этом случае мне интересно, какое отношение это имеет к расчету здесь ...
Матанстер

0

Хех, хотел бы я ответить на этот вопрос, но фанаты, создающие API-интерфейсы, не предоставляют базовых вещей и временами слишком абстрагируются.

Между прочим, у меня есть 40-летний опыт проектирования пользовательского интерфейса и программного обеспечения, и я настаивал на том, чтобы иметь это, кажется, навсегда, еще до появления драйверов "VESA" :).

Для сенсорного экрана у меня была вещь, которую я назвал «fingerSize ()», которая представляла собой количество пикселей, равное 1 см (очень близко к диаметру средней области касания пальца), но исходное значение - «dpcm».

Еще одна вещь, которую вы хотите от дисплея, - это «угол обзора». Тип устройства отображения для просмотра и сенсорная функция в значительной степени определяют расстояние просмотра.

    (Not code but I wanted fixed width font)

    Hand held - Phone/Tablet         25cm 
    Touch screen / Desktop Monitor   40cm         ( seated or standing at a counter
                                                    with partially extended arm )
    "Personal" Touch kiosk        50cm -> 80cm ( a bit further away standing 
                                                 extended arms and standing back 
                                                 to view )
    Presentation Screen.          any distance ( angle of view derived from pixel
                                                 width of device. An ideal conventional cinema 
                                                 seat (as opposed to imax or immersive) 
                                                 you want about 50 degrees
                                                 between edges of the screen. from viewer POV )

    So what you want universally available is:

    device usage type.
    finger size in pixels (dots per CM)
    pixel dimensions of display.

    Then internally, when laying out and drawing you want the size/shape of a pixel 
    for the current transform. 

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


-1

Вы можете приблизительно оценить размер, но это не совсем точно.

Я собрал пример, который я протестировал на паре устройств, чтобы увидеть, каковы были результаты. Мой iPhone 6 возвращает значения примерно на 33% больше. Мой 27-дюймовый настольный монитор на моем Mac сообщил как 30-дюймовый монитор.

var $el = document.createElement('div');
$el.style.width = '1cm';
$el.style.height = '1cm';
$el.style.backgroundColor = '#ff0000';
$el.style.position = 'fixed';
$el.style.bottom = 0;
document.body.appendChild($el);
var screenDiagonal = Math.sqrt(Math.pow((window.screen.width / $el.offsetWidth), 2) + Math.pow((window.screen.height / $el.offsetHeight), 2));
var screenDiagonalInches = (screenDiagonal / 2.54);
var str = [
  '1cm (W): ' + $el.offsetWidth + 'px',
  '1cm (H): ' + $el.offsetHeight + 'px',
  'Screen width: ' + window.screen.width + 'px',
  'Screen height: ' + window.screen.height + 'px',
  'Browser width: ' + window.innerWidth + 'px',
  'Browser height: ' + window.innerHeight + 'px',
  'Screen available width: ' + window.screen.availWidth + 'px',
  'Screen available height: ' + window.screen.availHeight + 'px',
  'Screen width: ' + (window.screen.width / $el.offsetWidth).toFixed(2) + 'cm',
  'Screen height: ' + (window.screen.height / $el.offsetHeight).toFixed(2) + 'cm',
  'Screen diagonal: ' + screenDiagonal.toFixed(2) + 'cm',
  'Screen diagonal: ' + screenDiagonalInches.toFixed(2) + 'in',
  'Device Pixel Ratio: ' + (window.devicePixelRatio || 1)
].join('\n');
var $pre = document.createElement('pre');
$pre.innerHTML = str;
document.body.appendChild($pre);

http://codepen.io/kus/full/xOAPYB/


1
Мои 40 дюймов сообщаются как 22 дюйма.
RobotRock

Не совсем точно для меня. Думаю, проблема в том window.devicePixelRatio. Это 1 на экране Apple Thunderbolt и 2 на сенсорной панели Macbook Pro 15 дюймов. Всегда ли это значение целое число? Это не имеет смысла, поскольку это соотношение. Другие элементы: stackoverflow.com/questions/16385573/…
Tom
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.