Ottenere le dimensioni fisiche dello schermo / dpi / densità di pixel in Chrome su Android


88

Domanda

Esiste un modo sicuro per ottenere le dimensioni fisiche dello schermo effettivamente corrette in Chrome, su Android? Se necessario, le vecchie versioni di Chrome e Android possono essere escluse.

Ricerca precedente

Ci sono numerose domande senza uscita sullo stackoverflow su come ottenere le dimensioni fisiche effettive dello schermo di un dispositivo da javascript (o css). Sembra che non ci sia convergenza tra la standardizzazione delle API HTML e le implementazioni effettive del browser in quanto, per non parlare dell'implementazione del browser, si basa sulle API del sistema operativo che a loro volta si basano sull'hardware che fornisce le giuste informazioni.

Alcune risposte precedenti, tra l'altro, sono arcane (anno 2011 e simili) nell'assumere una certa densità di pixel che prevaleva in quel momento, e quindi inutile. Altri si riferiscono al webkit mentre Chrome Blink potrebbe aver sostituito il webkit in Chrome (?).

Vorrei esplorare l'esistenza di una soluzione semplice vincolando le cose solo a Chrome su Android.

Nota

Si tratta di una soluzione javascript (o css) all'interno del browser, non di una soluzione per un'app nativa.


21
È semplicemente sbagliato. La mia interfaccia utente vuole sapere cose come quanto deve essere grande un pulsante come lo vede l'utente. potresti pensare troppo come sviluppatore di codice in questo;)
matanster

12
La dimensione di un pulsante, ad esempio, non dovrebbe essere una percentuale della visualizzazione, ma piuttosto grande abbastanza da poter essere toccata. Non sono sicuro di come abbia senso per un design di alta qualità.
matanster

16
@matt è assolutamente corretto. Uno degli aspetti più importanti di Web UX / UI, specialmente in un mondo con dita grasse, è assicurarsi che i pulsanti siano sia appropriati per il puntatore - in questo caso, un dito - sia adeguatamente dimensionati per la distanza di visualizzazione dallo schermo agli occhi. Questo nuovo regno di dispositivi mobili ha complicato la questione, quindi il rilevamento delle dimensioni fisiche dello schermo è ancora più fondamentale.
Jason T Featheringham

7
Sono al 100% con te @matt. Non capisco perché Mozilla e Google non possano darci una proprietà JavaScript come window.screenDensityquella contenente i pixel fisici per pollice del dispositivo che tu e io, Matt, possiamo prenderla da lì. window.screenHeighte anche window.screenWidthin millimetri fisici sarebbe bello.
trusktr

7
@Kinlan La dimensione fisica dello schermo è importante in generale. Questo è il motivo per cui lo sviluppo nativo è più potente dello sviluppo web al momento. In un ambiente nativo, posso creare un pulsante largo 1 pollice (mondo reale), su tutti i dispositivi moderni, ad esempio. Questo non è attualmente possibile in un ambiente web, per quanto ne so. Mi sono perso qualcosa?
trusktr

Risposte:


118

Non puoi davvero ottenere le dimensioni fisiche reali o il DPI effettivo e anche se potessi, non puoi farci nulla.

Questa è una storia piuttosto lunga e complessa, quindi perdonami.

Il web e tutti i browser definiscono 1px come un'unità chiamata pixel CSS. Un pixel CSS non è un pixel reale, piuttosto un'unità considerata pari a 1/96 di pollice in base all'angolo di visualizzazione del dispositivo. Viene specificato come pixel di riferimento .

Il pixel di riferimento è l'angolo visivo di un pixel su un dispositivo con una densità di pixel di 96 dpi e una distanza dal lettore della lunghezza di un braccio. Per una lunghezza nominale del braccio di 28 pollici, l'angolo visivo è quindi di circa 0,0213 gradi. Per la lettura a distanza di un braccio, 1px corrisponde quindi a circa 0,26 mm (1/96 di pollice).

In 0,26 mm di spazio potremmo avere molti pixel reali del dispositivo.

Il browser lo fa principalmente per motivi legacy - la maggior parte dei monitor era a 96 dpi quando è nato il Web - ma anche per coerenza, ai "vecchi tempi" un pulsante da 22 px su uno schermo da 15 pollici a 800x600 sarebbe il doppio di un pulsante da 22 px su un monitor da 15 pollici a 1600x1200. In questo caso il DPI dello schermo è effettivamente 2x (il doppio della risoluzione in orizzontale ma nello stesso spazio fisico). Questa è una brutta situazione per il Web e le app, quindi la maggior parte dei sistemi operativi ha escogitato molti modi per astrarre i valori dei pixel in unità indipendenti dal dispositivo (DIPS su Android, PT su iOS e CSS Pixel sul web ).

Il browser iPhone Safari è stato il primo (a mia conoscenza) ad introdurre il concetto di viewport. Questo è stato creato per abilitare il rendering di applicazioni in stile desktop completo su un piccolo schermo. La visualizzazione è stata definita per essere larga 960 px. Questo essenzialmente ha ingrandito la pagina 3x (iPhone era originariamente 320px) quindi 1 pixel CSS è 1/3 di un pixel fisico. Quando hai definito una visualizzazione, potresti fare in modo che questo dispositivo corrisponda a 1 pixel CSS = 1 pixel reale a 163 dpi.

Utilizzando un viewport in cui la larghezza è "device-width" ti evita di dover impostare la larghezza del viewport in base al dispositivo sulla dimensione ottimale in pixel CSS, il browser lo fa per te.

Con l'introduzione dei dispositivi a doppio DPI, i produttori di telefoni cellulari non volevano che le pagine per dispositivi mobili apparissero più piccole del 50%, quindi hanno introdotto un concetto chiamato devicePixelRatio (il primo su mobile webkit credo), questo consente loro di mantenere 1 pixel CSS all'incirca 1 / 96esimo di pollice ma ti fa capire che le tue risorse come le immagini potrebbero dover essere il doppio delle dimensioni. Se guardi la serie iPhone, tutti i loro dispositivi dicono che la larghezza dello schermo in pixel CSS è 320px anche se sappiamo che non è vero.

Pertanto, se hai impostato un pulsante in modo che sia 22px nello spazio CSS, la rappresentazione sullo schermo fisico è il rapporto pixel del dispositivo di 22 *. In realtà dico questo, non è esattamente questo perché il rapporto pixel del dispositivo non è mai esatto, i produttori di telefoni lo impostano su un bel numero come 2.0, 3.0 anziché 2.1329857289918 ....

In sintesi, i pixel CSS sono indipendenti dal dispositivo e non dobbiamo preoccuparci delle dimensioni fisiche degli schermi e delle densità di visualizzazione, ecc.

La morale della storia è: non preoccuparti di capire la dimensione fisica dei pixel dello schermo. Non ne hai bisogno. 50px dovrebbe avere più o meno lo stesso aspetto su tutti i dispositivi mobili, potrebbe variare leggermente, ma CSS Pixel è il nostro modo indipendente dal dispositivo per creare documenti e interfacce utente coerenti

Risorse:


1
@matt sarà lo stesso sui tablet. Come è con i libri Mac retina. L'obiettivo è che il "pixel CSS" sia relativamente uniforme su tutte le piattaforme, soprattutto se imposti la larghezza della visualizzazione = larghezza del dispositivo.
Kinlan

14
Hai detto "non puoi farci niente". Non sono d'accordo. Con queste informazioni sarei in grado di impostare un carattere che sia sempre di 16 punti (16 / 72esimi di pollice reale) in altezza. Questo è inestimabile e uno dei motivi per cui lo sviluppo nativo continua ad essere più potente dello sviluppo web.
trusktr

8
In realtà, un uso perfettamente ragionevole delle dimensioni reali dello schermo in pixel è il rendering di un'immagine di sfondo con la risoluzione appropriata.
WhyNotHugo

2
"50px dovrebbe essere più o meno lo stesso su tutti i dispositivi mobili", prova che utilizzando, ad esempio, un telefono da 4 pollici 1200 x 1920 e un tablet da 10 pollici 1000 x 600 uno accanto all'altro.
iloveregex

6
Non sono d'accordo anche con "non puoi farci niente": puoi rilevare se il dispositivo è un telefono o un tablet in modo affidabile e presumere che l'utente possa facilmente puntare la parte superiore dello schermo con il dito o meno.
Brian Cannard

11

Sulla base della risposta di Matt, ho fatto un test:

// 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\"?");

Questo è l'output:

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

No.

Quindi non sembra esserci ancora alcun modo per ottenere valori fisici reali in un browser web.


Non sono sicuro a quale risposta ti riferisci (non vedo "Matt" da nessuna parte), ma ottengo NaN perché svgEl.screenPixelToMillimeterXapparentemente non è stato definito.
Michael

6

Puoi creare qualsiasi elemento della pagina e impostarne la larghezza utilizzando unità fisiche reali. Per esempio

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

E poi ottieni la sua larghezza in pixel. Ad esempio, il codice html di seguito (ho usato JQuery) mostra la larghezza dello schermo del dispositivo in centimetri

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

alert(widthCM);
</script>

Wow, non mi sono mai reso conto che potresti farlo con CSS. Quanto è accurato? Come fa il tuo browser a conoscere le dimensioni fisiche del tuo schermo? La compatibilità del browser per questo su caniuse.com è da qualche parte? Non riesco a trovarlo.
Jake Wilson

4
Il sito W3C dice: "In passato, i CSS richiedevano che le implementazioni visualizzassero correttamente le unità assolute anche sugli schermi dei computer. Ma poiché il numero di implementazioni errate era superiore a quelle corrette e la situazione non sembrava migliorare, CSS ha abbandonato tale requisito nel 2011. Attualmente , le unità assolute devono funzionare correttamente solo sull'output stampato e su dispositivi ad alta risoluzione. I CSS non definiscono il significato di "alta risoluzione". Ma poiché le stampanti di fascia bassa oggigiorno partono da 300 dpi e gli schermi di fascia alta sono a 200 dpi, il limite è probabilmente una via di mezzo ".
Mike

1
Penso che il browser come qualsiasi altra applicazione nativa possa ottenere la risoluzione del dispositivo tramite l'API del sistema operativo, fornita al sistema operativo dal driver del dispositivo. La precisione dipende da queste informazioni.
Mike

Ma la risoluzione del dispositivo non è la stessa delle dimensioni fisiche effettive. Un laptop da 14 "e un laptop da 15" potrebbero avere la stessa risoluzione.
Jake Wilson

6
No! Non puoi. 10 cm in Css avranno dimensioni diverse nella realtà. È pura questione di fortuna se avrà effettivamente 10 cm, 12 cm o 7 cm. Ecco la mia demo di jsfiddle basata su quella soluzione che restituisce valori errati, poiché i browser si comportano sempre come se avessero pixel per pollice (dpi): jsfiddle.net/Lzsm3zo9
Dariusz Sikorski

5

Puoi ottenere queste informazioni con WURFL:

Proprietà di visualizzazione del dispositivo

Gli attributi sono chiamati:

resolution_(width|height)

physical_display_(width|height)

Versione lunga:

La strategia migliore e più affidabile per raggiungere questo obiettivo è inviare il user agent stringdal browser a un DB simile WURFL(o un altro) aggiornato in grado di fornire le informazioni necessarie.

Stringa agente utente

Questa è un'informazione che tutti i browser moderni possono fornire; espone le informazioni sul dispositivo e sul suo sistema operativo. Semplicemente non è abbastanza significativo per la tua applicazione senza l'aiuto di un dizionario come WURFL.

WURFL

Si tratta di un database comunemente utilizzato per rilevare le proprietà del dispositivo.

Con esso, potresti essere in grado di supportare con precisione la maggior parte dei dispositivi popolari sul mercato. Vorrei pubblicare una demo del codice ma una è disponibile con il download sul WURFLsito. È possibile trovare una demo di questo tipo nella cartella examples / demo scaricata con la libreria.

Scarica WURFL

Ulteriori informazioni e spiegazioni sul controllo delle dimensioni fisiche e della risoluzione: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286


3

Come complemento alla risposta "non c'è una buona soluzione a questo problema", controlla le unità che puoi usare su 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.

Con questa descrizione sembra che ci sia una soluzione. cm, mmE inpotrebbe essere utilizzato per disegnare qualcosa con le stesse dimensioni indipendentemente dalle dimensioni dello schermo e la risoluzione. Con questo in mente, puoi aspettarti che almeno uno di px, pto pcpossa essere usato per disegnare a livello di pixel, per qualunque precisione tu voglia usare (altrimenti, che senso ha avere milioni di pixel, giusto?). Beh no. Tutte le unità sono frazioni di un'unità metrica, rendendo tutte queste unità solo scale diverse. E la cosa peggiore della storia è il fatto che nessuno di questi è accurato. Gioca con l'esempio di w3schools (traccia una linea di 20 cm e misurala con un righello).

Così, alla fine: - non c'è modo di disegnare qualcosa con dimensioni fisiche in modo accurato (che dovrebbe essere il caso cm, mm, in, e, infine, pte pc). - non c'è modo di disegnare qualcosa con la stessa dimensione indipendentemente dalle dimensioni dello schermo e dalla risoluzione (che dovrebbe essere il caso almenopx ).

Questo è sia un problema di implementazione (la dimensione effettiva dello schermo non viene utilizzata) che un problema di progettazione (perché dovrebbe pxessere indipendente dalla dimensione dello schermo mentre ci sono già così tante unità per quello).


2

Ho affrontato questo problema con uno dei miei progetti web http://www.vinodiscover.com La risposta è che non puoi sapere con certezza quale sia la dimensione fisica, ma puoi ottenere un'approssimazione. Usando JS e / o CSS, puoi trovare la larghezza e l'altezza del viewport / schermo e la densità dei pixel usando le media query. Ad esempio: iPhone 5 (326 ppi) = 320px per 568px e una densità di 2.0 pixel, mentre un Samsung Galaxy S4 (441ppi) = 360px x 640px e una densità di 3.0 pixel. Effettivamente una densità di 1.0 pixel è di circa 150 ppi.

Detto questo, ho impostato il mio CSS per mostrare 1 colonna quando la larghezza è inferiore a 284px, indipendentemente dalla densità dei pixel; poi due colonne tra 284px e 568px; quindi 3 colonne sopra 852 px. È molto più semplice di quanto sembri, dal momento che i browser ora eseguono automaticamente i calcoli della densità dei pixel.

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


3
Nello sviluppo nativo puoi ottenere il valore esatto. +1 per nativo, -1 per web.
trusktr

Puoi ottenere la dimensione fisica esatta su Android?
Apollo Clark


2

In risposta alla risposta di zehelvion sull'utilizzo di WURFL per trovare la risoluzione, vale anche la pena ricordare che WURFL è disponibile anche come snippet JavaScript .

Nell'edizione gratuita offerta su wurfl.io , tuttavia , non otterrai informazioni sullo schermo e sulla risoluzione (solo nome del dispositivo, fattore di forma e dispositivo mobile / non mobile), ma è disponibile anche una versione commerciale con più funzionalità disponibili qui .


3
Suggerisco che sia nei commenti a quella particolare risposta.
darkgaze

1
questa è una soluzione incredibilmente complicata a qualcosa che dovrebbe essere fornito in modo nativo dal browser.
Michael

2

I pixel CSS non sono realmente il nostro "pixel indipendente dal dispositivo". La piattaforma Web è costituita da una varietà di tipi di dispositivi. Sebbene il pixel CSS sembri abbastanza coerente sui palmari, sarà più grande del 50% su un tipico monitor desktop a 96 dpi. Vedi la mia domanda . In alcuni casi non è una cosa negativa, ad esempio i caratteri dovrebbero essere più grandi su uno schermo più grande, poiché la distanza dall'occhio è maggiore. Ma le dimensioni degli elementi dell'interfaccia utente dovrebbero essere abbastanza coerenti. Supponiamo che la tua app abbia una barra in alto, preferiresti che abbia lo stesso spessore su desktop e cellulari, per impostazione predefinita sarà più piccola del 50%, il che non va bene, perché gli elementi toccabili dovrebbero essere più grandi. L'unica soluzione alternativa che ho trovato è applicare stili diversi in base al DPI del dispositivo.

Puoi ottenere DPI dello schermo in JavaScript con window.devicePixelRatio. O query 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*/
    }

Tuttavia, non so come potrebbe funzionare l'applicazione su un monitor desktop ad alta risoluzione. Forse gli elementi sarebbero troppo piccoli. È davvero un peccato che la piattaforma web non offra di meglio. Immagino che l'implementazione di dip non sarebbe troppo difficile.


no, non puoi. le media query stanno facendo questa stupida "presunzione di 96 dpi", cioè ti stanno mentendo su quale sia il DPI letto.
Michael

1

Ho notato nei tuoi commenti che in realtà eri preoccupato delle dimensioni che i pulsanti e così via appaiono allo spettatore.

Avevo lo stesso problema, finché non ho scoperto che si trattava solo di aggiungere un meta tag all'intestazione HTML per impostare la scala iniziale:

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



0

Utilizzando la funzione getPPI () ( Web mobile: come ottenere la dimensione fisica dei pixel? ), Per ottenere un ID di un pollice utilizzare questa formula:

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
perché pixelDepth ?! non è pixelDepth correlato alla profondità del colore, nel qual caso mi chiedo quanto sia rilevante per il calcolo qui ....
matanster

0

Vorrei poter rispondere a questa domanda, ma i fanatici della creazione di API non forniscono le necessità di base e le cose astratte un po 'troppo a volte.

A proposito, ho 40 anni di esperienza nella progettazione di interfacce utente e software e ho spinto per avere proprio questo per quello che sembra un'eternità da prima dei giorni dei driver "VESA" :).

Per il touch screen avevo una cosa che ho chiamato "fingerSize ()" che era il numero di pixel di 1 cm (molto vicino al diametro dell'area di tocco media del dito) ma il datmum principale è "dpcm".

L'altra cosa che vuoi per un display è l '"angolo di visualizzazione". Il tipo di dispositivo di visualizzazione per la visualizzazione e la funzione touch definisce praticamente la distanza di visualizzazione.

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

Questo è ciò che cerchiamo di fornire nelle nostre API, ma in molti casi è difficile da ottenere.


-1

Puoi ottenere una stima approssimativa delle dimensioni, ma non è accurata.

Ho messo insieme un esempio che ho testato su un paio di dispositivi per vedere quali sono stati i risultati. Il mio iPhone 6 restituisce valori maggiori del 33% circa. Il mio monitor desktop da 27 "sul mio Mac è stato segnalato come un monitor da 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
Il mio 40 pollici è stato segnalato come 22 pollici.
RobotRock

Non è accurato nemmeno per me. Penso che il problema sia dovuto a window.devicePixelRatio. È 1 su uno schermo Apple Thunderbolt e 2 su un Macbook Pro Touchbar da 15 ". Questo valore è sempre un numero intero? Non avrebbe senso poiché è un rapporto. Altri elementi: stackoverflow.com/questions/16385573/…
Tom
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.