Отримання фізичних розмірів екрана / точок на дюйм / щільності пікселів у Chrome на Android


88

Питання

Чи є безпечний спосіб отримати фактично правильні фізичні розміри екрана в Chrome на Android? За необхідності, старі версії Chrome та Android можуть бути поза межами сфери дії.

Попередні дослідження

Існує численні тупикові запитання щодо stackoverflow щодо отримання фактичних фізичних розмірів екрану пристрою зсередини javascript (або css). Здається, що в цьому немає збіжності між стандартизацією html api та реальними реалізаціями браузера, не кажучи вже про те, що реалізація браузера покладається на OS api, які, в свою чергу, покладаються на обладнання, що забезпечує правильну інформацію.

Деякі попередні відповіді, до речі, є загадковими (2011 рік і тому подібні), які передбачають певну щільність пікселів, яка панувала на той час, і тому марна. Інші стосуються веб-набору, тоді як моргання Chrome, можливо, замінило веб-набір у хромі (?).

Я хотів би дослідити існування простого рішення, обмеживши речі лише Chrome на Android.

Примітка

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


21
Це просто неправильно. Мій користувальницький інтерфейс хоче знати такі речі, як, наскільки великою повинна бути кнопка, як це бачить користувач. можливо, ви занадто багато думаєте про це як про розробника коду;)
matanster

12
Наприклад, розмір кнопки не повинен становити відсоток від області перегляду - а досить великий, щоб торкнутися. Я не впевнений, як це має сенс для високоякісного дизайну.
matanster

16
@matt абсолютно правильний. Одним з найважливіших аспектів веб-UX / UI, особливо у світі жирних пальців, є переконання, що кнопки відповідають як покажчику - у цьому випадку пальцю, так і відповідному розміру для відстані огляду від екрана до ока. Ця нова сфера мобільних пристроїв ускладнила справу, тому фізичне визначення розміру екрану ще важливіше.
Jason T Featheringham

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

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

Відповіді:


118

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

Це досить довга і складна історія, тому пробачте мене.

Інтернет і всі браузери визначають 1px як одиницю, яка називається пікселем CSS. Піксель CSS - це не справжній піксель, а одиниця виміру, яка вважається 1/96 дюйма на основі кута огляду пристрою. Це вказано як контрольний піксель .

Еталонний піксель - це кут зору одного пікселя на пристрої з щільністю пікселів 96 dpi та відстанню від зчитувача на відстані витягнутої руки. Отже, для номінальної довжини руки 28 дюймів кут зору становить приблизно 0,0213 градуса. Таким чином, для зчитування на відстані витягнутої руки 1px відповідає приблизно 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 реальному пікселю зі швидкістю 163 dpi.

Використовуючи вікно перегляду, де ширина дорівнює "ширині пристрою", ви звільняєтесь від необхідності встановлювати ширину вікна перегляду для кожного пристрою на оптимальний розмір пікселів 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 так само буде і на планшетах. Як це відбувається з книгами Mac Retina. Мета полягає в тому, що "CSS Pixel" є відносно рівномірним на всіх платформах, особливо якщо ви встановите ширину області перегляду = ширина пристрою.
Кінлан

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мабуть, не визначено.
Michael

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 dpi, а високоякісні екрани - з 200 dpi, межа, можливо, десь посередині ".
Майк,

1
Я думаю, що браузер, як і будь-яка інша рідна програма, може отримувати роздільну здатність пристрою через OS API, наданий ОС драйвером пристрою. Точність залежить від цієї інформації.
Майк,

Але роздільна здатність пристрою не однакова з реальними фізичними розмірами. 14-дюймовий і 15-дюймовий ноутбуки можуть мати однакову роздільну здатність.
Jake Wilson,

6
Немає! Ви не можете. 10 см у Css матимуть різний розмір насправді. Чиста справа удачі, якщо вона насправді матиме 10 см, 12 см або 7 см. Ось моя демонстрація jsfiddle на основі цього рішення, що повертає неправильні значення, оскільки браузери завжди поводяться так, ніби мають пікселі на дюйм (dpi): jsfiddle.net/Lzsm3zo9
Dariusz Sikorski,

5

Ви можете отримати цю інформацію за допомогою WURFL:

Властивості відображення пристрою

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

resolution_(width|height)

physical_display_(width|height)

Довга версія:

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

Рядок агента користувача

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

WURFL

Це база даних, яка зазвичай використовується для виявлення властивостей пристрою.

З його допомогою ви зможете точно підтримувати більшість популярних пристроїв на ринку. Я б опублікував демонстраційний код, але такий доступний із завантаженням на WURFLсайті. Ви можете знайти таку демонстраційну версію в папці із прикладами / демонстраційною програмою, яка завантажується з бібліотекою.

Завантажте 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 ppi) = 320px на 568px та щільність 2,0 пікселя, тоді як Samsung Galaxy S4 (441ppi) = 360px x 640px та щільність 3,0 пікселя. Фактично щільність 1,0 пікселя становить близько 150 ppi.

Враховуючи це, я встановив CSS, щоб він показував 1 стовпець, коли ширина менше 284px, незалежно від щільності пікселів; потім два стовпці між 284px і 568px; потім 3 стовпці вище 852 пікселів. Це набагато простіше, ніж здається, оскільки браузери тепер обчислюють щільність пікселів автоматично.

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


3
У власній розробці ви можете отримати точне значення. +1 для рідної мови, -1 для Інтернету.
trusktr

Чи можете ви отримати точний фізичний розмір в Android?
Apollo Clark


2

Як відповідь на відповідь zehelvion щодо використання WURFL для пошуку дозволу, варто також згадати, що WURFL також доступний як фрагмент JavaScript .

У безкоштовному виданні, пропонованому на сайті wurfl.io , ви не отримаєте інформації про екран та роздільну здатність (лише ім'я пристрою, форм-фактор та мобільний / не мобільний), але тут також є комерційна версія з додатковими можливостями .


3
Я пропоную це бути у коментарях до цієї конкретної відповіді.
darkgaze

1
це смішно складне рішення для чогось, що просто має бути надане браузером.
Майкл

2

CSS-пікселі насправді не є нашим "незалежним від пристрою пікселем". Веб-платформа складається з різноманітних типів пристроїв. Хоча CSS-піксель, здається, виглядає досить послідовно на портативних ПК, він буде на 50% більшим на типовому моніторі на 96 dpi. Дивіться моє запитання . У деяких випадках це насправді не погано, наприклад, шрифти повинні бути більшими на більшому екрані, оскільки відстань до ока більша. Але розміри елементів інтерфейсу користувача повинні бути досить послідовними. Скажімо, у вашому додатку є верхня панель, ви б хотіли, щоб вона була однакової товщини на робочому столі та мобільних телефонах, за замовчуванням вона буде на 50% меншою, що недобре, оскільки дотичні елементи повинні бути більшими. Єдине обхідне рішення, яке я знайшов, полягає у застосуванні різних стилів на основі DPI пристрою.

Ви можете отримати екранний 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*/
    }

Я не знаю, як застосування цього могло б працювати на моніторі настільного ПК з високою точністю на дюйм. Можливо, елементи були б замалі. Насправді прикро, що веб-платформа не пропонує нічого кращого. Я думаю, що реалізація dip не буде надто складною.


ні, ти не можеш. медіа-запити роблять цю дурну глупоту "припустимо 96 dpi", тобто вони брешуть вам про те, що таке прочитаний 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

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 пов’язаний з глибиною кольору, і в цьому випадку мені цікаво, як це стосується обчислення тут ....
matanster

0

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

До речі, я маю 40-річний досвід користувальницького інтерфейсу та дизайну програмного забезпечення, і наполягаю на тому, щоб мати саме це, що здається назавжди ще з часів водіїв "VESA" :).

Для сенсорного екрану у мене була річ, яку я назвав "fingerSize ()", тобто кількість пікселів, що дорівнює 1 см (дуже близька до діаметра середньої площі дотику пальця), але кореневий datmum - "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/…
Том,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.