Cómo obtener las dimensiones físicas de la pantalla / dpi / densidad de píxeles en Chrome en Android

Pregunta

¿Existe una forma segura de obtener las dimensiones físicas de la pantalla realmente correcta en Chrome, en Android? Si es necesario, las versiones anteriores de Chrome y Android pueden quedar fuera del alcance.

Investigaciones anteriores

Existen numerosas preguntas sin fin sobre stackoverflow acerca de cómo obtener las dimensiones reales de la pantalla física de un dispositivo desde dentro de javascript (o css). Parece que no hay convergencia entre la normalización api html y las implementaciones reales del navegador en que, por no hablar de la implementación del navegador se basa en api del sistema operativo que a su vez dependen de hardware que proporciona la información correcta.

Algunas respuestas previas por cierto son arcanas (año 2011 y similares) al asumir una determinada densidad de píxeles que prevaleció en ese momento, y por lo tanto inútil. Otros se relacionan con el webkit, pero Chrome blink reemplazó el webkit en cromo (?).

Me gustaría explorar la existencia de una solución simple restringiendo las cosas a sólo Chrome en Android.

Nota

Esto es todo acerca de una solución javascript (o css) dentro del navegador, no una solución para una aplicación nativa.

Realmente no se pueden obtener las dimensiones físicas reales o el DPI real e incluso si se puede, no se puede hacer nada con ellos.

Esta es una historia bastante larga y compleja, así que perdóname.

La web y todos los navegadores definen 1px como una unidad denominada píxel CSS. Un píxel CSS no es un píxel real, sino una unidad que se considera 1 / 96th de una pulgada en función del ángulo de visión del dispositivo. Esto se especifica como un píxel de referencia .

El píxel de referencia es el ángulo visual de un píxel en un dispositivo con una densidad de píxeles de 96dpi ya una distancia del lector de una longitud de brazo. Para una longitud nominal del brazo de 28 pulgadas, el ángulo visual es por lo tanto alrededor de 0.0213 grados. Para la lectura a la longitud del brazo, 1px corresponde así a aproximadamente 0,26 mm (1/96 pulgadas).

En 0.26mm de espacio podríamos tener muchos píxeles reales del dispositivo.

El navegador hace esto principalmente por razones de legado – la mayoría de los monitores eran 96dpi cuando nació la web – pero también para la consistencia, en los "viejos tiempos" un botón 22px en una pantalla de 15 pulgadas a 800×600 sería el doble del tamaño de un botón 22px en Un monitor de 15 pulgadas a 1600×1200. En este caso el DPI de la pantalla es en realidad 2x (dos veces la resolución horizontalmente, pero en el mismo espacio físico). Esta es una mala situación para la web y las aplicaciones, por lo que la mayoría de los sistemas operativos idearon muchas formas de abstraer los valores de píxeles en unidades independientes del dispositivo (DIPS en Android, PT en iOS y CSS Pixel en la web ).

El navegador iPhone Safari fue el primero (a mi entender) en introducir el concepto de una ventana gráfica. Esto se creó para permitir que las aplicaciones de estilo de escritorio completas se renderizaran en una pequeña pantalla. La ventana de visualización se definió como 960px de ancho. Esto ampliado esencialmente la página hacia fuera 3x (iphone era originalmente 320px) así que 1 pixel del CSS es 1 / 3rd de un pixel físico. Cuando definió una ventana de visualización, aunque podría obtener este dispositivo para que coincida con 1 píxel CSS = 1 píxel real en 163 ppp.

Mediante el uso de una ventana de visualización donde el ancho es "anchura de dispositivo" le libera de tener que establecer el ancho de la ventana de visualización por dispositivo al tamaño óptimo de píxeles CSS, el navegador lo hace por usted.

Con la introducción de dispositivos DPI dobles, los fabricantes de teléfonos móviles no querían que las páginas móviles aparezcan un 50% más pequeñas, por lo que introdujeron un concepto llamado devicePixelRatio (primero en webkit móvil, creo), esto les permite mantener 1 píxel CSS aproximadamente 1 / 96th de una pulgada pero le dejó entender que sus activos tales como imágenes pueden necesitar ser dos veces el tamaño. Si nos fijamos en la serie de iPhone todos sus dispositivos dicen que el ancho de la pantalla en píxeles CSS es de 320 píxeles , aunque sabemos que esto no es cierto.

Por lo tanto, si usted hizo un botón para ser 22px en el espacio CSS, la representación en la pantalla física es 22 * ​​ratio de píxeles del dispositivo. En realidad digo esto, no es exactamente esto porque la relación de píxeles del dispositivo tampoco es exacta tampoco, los fabricantes de teléfonos establecerlo a un número agradable como 2.0, 3.0 en lugar de 2.1329857289918 ….

En resumen, los píxeles CSS son independientes del dispositivo y no tengamos que preocuparnos por los tamaños físicos de las pantallas y las densidades de visualización, etc.

La moraleja de la historia es: No se preocupe por entender el tamaño de píxel físico de la pantalla. No lo necesitas. 50px debe parecer más o menos lo mismo en todos los dispositivos móviles puede variar un poco, pero el CSS Pixel es nuestro dispositivo de manera independiente para construir documentos consistentes y la interfaz de usuario

Recursos:

Sobre la base de la respuesta de Matt, hice una prueba:

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

Esta es la salida:

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

Nope.

Así que parece que no hay manera de obtener valores físicos reales en un navegador web todavía.

Puede obtener esa información con WURFL:

Propiedades de visualización del dispositivo

Los atributos se llaman:

 resolution_(width|height) physical_display_(width|height) 

Versión larga:

La estrategia mejor y más confiable para lograr esto es enviar la user agent string del user agent string desde el navegador a un DB como WURFL u otro DB actualizado que puede proporcionar la información necesaria.

Cadena de agente de usuario

Esta es una pieza de información que todos los navegadores modernos pueden proporcionar; Expone información sobre el dispositivo y su sistema operativo. No es lo suficientemente significativo para su aplicación sin la ayuda de un diccionario como WURFL .

WURFL

Esta es una base de datos comúnmente utilizada para detectar las propiedades del dispositivo.

Con él, puede ser capaz de apoyar con precisión la mayoría de los dispositivos populares en el mercado. Publicaría un código de demostración, pero uno está disponible con la descarga en el sitio WURFL . Puede encontrar esta demostración en la carpeta ejemplos / demo que se descarga con la biblioteca.

Descargar WURFL

Aquí hay más información y explicación sobre cómo comprobar el tamaño físico y la resolución: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286

Puede crear cualquier elemento de página y establecer su ancho utilizando unidades físicas reales. Por ejemplo

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

Y luego obtener su ancho en píxeles. Por ejemplo código html abajo (i utiliza JQuery) muestra el ancho de la pantalla del dispositivo en centímetros

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

He abordado este problema con uno de mis proyectos web http://www.vinodiscover.com La respuesta es que no se puede saber con certeza cuál es el tamaño físico, pero se puede obtener una aproximación. Utilizando JS y / o CSS, puede encontrar el ancho y la altura de la ventana de visualización / pantalla, y la densidad de píxeles utilizando consultas de medios. Por ejemplo: iPhone 5 (326 ppi) = 320px por 568px y una densidad de 2,0 píxeles, mientras que un Samsung Galaxy S4 (441ppi) = 360px x 640px y una densidad de 3,0 píxeles. Efectivamente una densidad de 1.0 píxeles es alrededor de 150 ppi.

Teniendo en cuenta esto, he establecido mi CSS para mostrar 1 columna cuando el ancho es inferior a 284px, independientemente de la densidad de píxeles; Entonces dos columnas entre 284px y 568px; Entonces 3 columnas por encima de 852px. Es mucho más simple de lo que parece, ya que los navegadores ahora hacen los cálculos de densidad de píxeles automáticamente.

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

Utilizando la función getPPI () ( Web móvil: cómo obtener tamaño de píxel físico? ), Para obtener una ID de una pulgada utilice esta fórmula:

 var ppi = getPPI(); var x = ppi * devicePixelRatio * screen.pixelDepth / 24; $('#Cubo').width (x); $('#Cubo').height(x); <div id="Cubo" style="background-color:red;"></div> 

Como respuesta a la respuesta de Zehelvion sobre el uso de WURFL para encontrar la resolución, también vale la pena mencionar que WURFL también está disponible como un fragmento de JavaScript .

En la edición gratuita que se ofrece en wurfl.io , no obtendrás información sobre la pantalla y la resolución (sólo el nombre del dispositivo, el factor de forma y móvil / no móvil), pero también hay una versión comercial con más capacidades disponibles aquí .

Los píxeles CSS no son realmente nuestro "píxel independiente del dispositivo". La plataforma Web consiste en una variedad de tipos de dispositivos. Mientras que los píxeles CSS parecen tener un aspecto bastante consistente en las computadoras de mano, será 50% más grande en un monitor de escritorio típico de 96dpi. Ver mi pregunta . Esto no es realmente una cosa mala en algunos casos, eg las fuentes deben ser más grandes en una pantalla más grande, puesto que la distancia al ojo es más grande. Pero las dimensiones del elemento ui deben ser bastante consistentes. Digamos que tu aplicación tiene una barra superior, preferirías que tuviera el mismo grosor en el escritorio y en los móviles, por defecto será 50% más pequeña, lo cual no es bueno, ya que los elementos táctiles deben ser más grandes. La única solución que he encontrado es aplicar diferentes estilos basados ​​en el dispositivo DPI.

Puede obtener DPI de pantalla en JavaScript con window.devicePixelRatio. O consulta 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*/ } 

No sé cómo aplicar esto funcionaría en un monitor de escritorio de alta resolución. Quizás los elementos serían demasiado pequeños. Es realmente una pena que la plataforma web no ofrece nada mejor. Supongo que la implementación de inmersión no sería demasiado difícil.

Ancho de elemento JqueryMobile

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

JqueryMobile Altura del elemento

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

Buena suerte Danny117

Puede obtener una estimación aproximada del tamaño, pero no es exacta.

He reunido un ejemplo que he probado en un par de dispositivos para ver cuáles fueron los resultados. Mi iPhone 6 devuelve valores aproximadamente 33% más grande. Mi 27 "monitor de escritorio en mi Mac informó como un monitor de 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); 
  • Android no reproduce audio html5 desde un intervalo
  • Cambiar el tamaño de elementos HTML en el cambio de orientación de Android
  • Uso de la aplicación Closure Library en Phonegap (Android)
  • Redirigir a appstore o google play
  • Usando javascript en android webview
  • cómo encontrar el recuento de elementos de la lista visible en el filtro de búsqueda jQuery mobile
  • Javascript: ¿Hay alguna solución para que Chrome para Android dispare a los oyentes de touchmove y touchend que no usen event.preventDefault ()?
  • Navegador por defecto de Samsung Mobile AngularJS $ http Solicitud POST fallando
  • ¿Cómo identificar un teléfono o tableta Android en jquery?
  • Carga de CSS móvil si el usuario está en Android
  • Escáner de código de barras ZXing para Webapps
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.