Imágenes fáciles de usar con valores altos de DPI

Las pantallas con alta densidad de píxeles se están convirtiendo rápidamente en la norma. Los creadores de contenido deben adaptarse a este hecho. Esta es una guía breve sobre cómo entregar imágenes de alta calidad en la Web hoy en día, sin polyfills, JavaScript, hackeos de CSS ni funciones del navegador que aún no se implementaron. En una palabra, sin cambios drásticos en tu flujo de trabajo.

Actualmente, existen muchas propuestas de imágenes responsivas, muchas de las cuales implican cambios significativos para el desarrollador web. El atributo <img> del seguimiento estándar srcset es difícil de implementar, en especial debido a la complejidad de la selección adicional basada en viewports del objeto srcset:

banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x

Aunque la propiedad image-set de CSS solo usa devicePixelRatio para decidir qué imagen cargar, obliga a los desarrolladores a escribir mucho lenguaje de marcado adicional para cada imagen.

Otras propuestas, como el elemento <picture>, son aún más detalladas. Además, no son de seguimiento estándar, por lo que su disponibilidad ubicua está aún más allá del atributo srcset. Las soluciones del lado del servidor y JavaScript son la única otra alternativa, pero estos enfoques tienen sus propias desventajas, como se explica en otros artículos.

En este artículo, se explican varios usos de las imágenes que se suelen encontrar en la Web y se proponen soluciones simples que funcionan tanto en pantallas con densidades de píxeles altas como en las comunes. Para los fines de este análisis, cualquier dispositivo que informe un valor de window.devicePixelRatio superior a 1 puede considerarse con valores altos de DPI, ya que eso significa que los píxeles de CSS no son lo mismo que los píxeles del dispositivo y que las imágenes se escalan verticalmente.

Aquí encontrarás un resumen:

  • Si es posible, usa imágenes de CSS/SVG en lugar de imágenes de trama.
  • Usa imágenes optimizadas de forma predeterminada para pantallas de alta densidad.
  • Usa archivos PNG para dibujos simples y pixel art (p. ej., logotipos).
  • Usa JPEG comprimidos para imágenes con diversos colores (p. ej., fotos).
  • Siempre configura tamaños explícitos (con CSS o HTML) en todos los elementos de las imágenes.

Dibujos simples y pixel art

A menudo, las imágenes pequeñas se pueden evitar por completo usando funciones de CSS o SVG. No es necesario usar imágenes para esquinas redondeadas, por ejemplo, ya que la propiedad border-radius de CSS es ampliamente compatible. Del mismo modo, las fuentes personalizadas son ampliamente compatibles, por lo que no se recomienda usar texto con imágenes.

Sin embargo, en algunos casos, como los logotipos, solo se puede avanzar con una imagen. Por ejemplo, este logotipo de Chrome tiene un tamaño natural de 256 x 256. En una pantalla Retina, puedes ver la asignación de alias a las líneas en diagonales y curvas, que se ve mal y fragmentada, en especial cuando se compara con el texto procesado de forma nítida:

Chrome 1
PNG 1

Dimensiones naturales: 256x256px, tamaño del recurso 31 kB, formato: PNG

¿Estás convencido? ¡Bien! Ahora, usemos una imagen de alta densidad. Es posible que te sientas tentado a ahorrar espacio almacenando tu logotipo como un archivo JPEG, pero esta no es una buena idea, ya que guardar logotipos y otros gráficos en un formato con pérdida tiende a introducir artefactos. En este caso, exageré el problema con una compresión muy alta, pero observa las bandas en los gradientes, las motas sobre los fondos blancos y las líneas desordenadas:

Chrome 2
Jpeg 2x

Dimensiones naturales: 512x512px, tamaño del recurso 13 kB, formato: JPEG

Lo que debes hacer con las imágenes relativamente pequeñas es usar archivos PNG 2x. Ten en cuenta que la diferencia de tamaño entre un archivo PNG de 1x y uno de 2x suele ser bastante alta (en este caso, 52 KB). Sin embargo, en el caso de un logotipo, es la cara de tu sitio web y lo primero que verán tus visitantes. Además, es lo último que verán los visitantes, ya que se restaura demasiada calidad a cambio del tamaño.

Este es el logotipo de Chrome en todo su esplendor, reducido a la mitad de sus dimensiones naturales para pantallas 2x:

Chrome 2
PNG 2

Dimensiones naturales: 512x512px, tamaño del recurso 83 kB, formato: PNG

El lenguaje de marcado para la renderización anterior es el siguiente:

<img src="chrome2x.png" style="width: 256px; height: 256px;"/>

Ten en cuenta que he especificado un ancho y una altura en la imagen. Esto es necesario porque el tamaño natural de la imagen es de 512 px. También es bueno para el rendimiento porque el motor de renderización tiene una buena idea del tamaño del elemento y no necesitará esforzarse demasiado para calcularlo.

Una posible optimización que podría funcionar es reducir el PNG de 24 bits a uno de 8 bits con paleta. Esto funciona para imágenes con una pequeña cantidad de colores, incluido el logotipo de Chrome. Para realizar esta optimización, puedes usar una herramienta como http://pngquant.org/. Se pueden ver algunas bandas aquí, pero este archivo pesa solo 13 KB, lo que equivale a un ahorro de 6x en comparación con el archivo PNG original de 512 x 512.

Chrome 2x 8 bits
PNG 2 de 8 bits

Dimensiones naturales: 512x512px, tamaño del recurso 13 kB, formato: PNG, 8-bit palette

Imágenes con una variedad de colores

Escribí un artículo de HTML5Rocks en el que encuestaba sobre una serie de técnicas de imágenes responsivas diferentes y también investigamos sobre la compresión de JPEG de 1x y 2x, y la comparación de los tamaños resultantes y la calidad visual. Este es un mosaico del artículo anterior:

&quot;Hello, World!&quot;.

Etiqueté las imágenes con su nivel de compresión (indicado por la calidad de JPEG), su tamaño (en bytes) y mi opinión subjetiva sobre su fidelidad visual comparativa (clasificada por números). Lo interesante aquí es que la imagen de 2x altamente comprimida (etiquetada 3) es más pequeña y se ve mejor que la imagen de 1x sin comprimir (etiquetada 4). En otras palabras, entre las imágenes 4 y 3, logramos mejorar la calidad de la imagen duplicando cada dimensión y aumentando considerablemente la compresión y, al mismo tiempo, reduciendo el tamaño en 2 KB.

Compresión, dimensiones y calidad visual

Quería obtener más información sobre las compensaciones entre el nivel de compresión, las dimensiones de la imagen, la calidad visual y el tamaño de la imagen. Realicé un estudio con la siguiente hipótesis basada en el estudio anterior:

Hipótesis

Con una compresión suficiente, una imagen 2x se verá equivalente a la misma imagen en tamaño 1x con alguna otra compresión (menor). Sin embargo, en este caso, la imagen de 2x altamente comprimida tendrá un tamaño más pequeño que la imagen de 1x.

Proceso

  • Con una imagen de 2x, genera la de 1x.
  • Comprime ambas imágenes en varios niveles.
  • Crea una página de prueba que muestre ambos conjuntos de imágenes en paralelo.
  • Busca el lugar en los dos conjuntos donde las imágenes son equivalentes.
  • Ten en cuenta los tamaños de imagen y los niveles de compresión equivalentes.
  • Pruébalo en pantallas de 1x y de 2x.

Creé una app para comparar imágenes en paralelo, similar a la vista de comparación de Lightroom. La idea es mostrar imágenes de 1x y 2x en paralelo, pero también permitirte acercar cualquier sección de la imagen para obtener más detalles. También puedes seleccionar entre los formatos JPEG y WebP, y cambiar la calidad de compresión para ver las comparaciones del tamaño del archivo y la calidad de la imagen. La idea es modificar la configuración de varias imágenes, determinar qué compensación de calidad de compresión, escalamiento y formato frente a calidad de imagen te resulte cómodo y usar esa configuración para todas tus imágenes.

Captura de pantalla de comparación

La herramienta en sí está disponible para que juegues con ella. Puedes acercar la imagen si seleccionas una subárea para acercarla.

Análisis

Diría que la calidad de la imagen es un asunto subjetivo. Además, es probable que tu caso de uso en particular indique dónde se encuentran tus prioridades en el espectro de fidelidad visual frente a espectro del tamaño de archivo. Además, los diferentes tipos de atributos de imagen reaccionan de manera diferente a la calidad del escalamiento y la compresión, por lo que es posible que una solución única para todos no funcione necesariamente en este caso. El objetivo de la herramienta es ayudarte a intuir las compresiones, las escalas y los formatos de calidad de la imagen.

Al jugar con el zoom de imágenes, algunas cosas se me hicieron evidentes rápidamente. En primer lugar, prefiero quality=30 dpr=2x imágenes en lugar de quality=90 dpr=1x por el aumento en el detalle. Estas imágenes también son comparables en tamaño de archivo (en el caso plano, la imagen 2x comprimida pesa 76 KB mientras que la 1x sin comprimir es de 80 KB).

Las excepciones a esta regla son las imágenes altamente comprimidas (quality<30) con gradientes. Estos tienden a tener bandas de colores, lo que es igual de malo sin importar la escala de la imagen. Las muestras de aves y autos que se encuentran en la herramienta son un ejemplo de esto.

Las imágenes WebP se ven mucho más limpias que las JPEG, especialmente en niveles bajos de compresión. Estas bandas de color parecen no ser un problema. Por último, las imágenes WebP son mucho más compactas.

Advertencias y aleta

Hacer que las imágenes se vean bien en pantallas de alta densidad es solo la mitad de los problemas relacionados con la imagen causados por una enorme variación en las pantallas. En algunos casos, es posible que quieras entregar imágenes completamente diferentes según el tamaño del viewport. Por ejemplo, el retrato de Obama podría ser apropiado para una pantalla del tamaño de un teléfono, pero el soporte frente a él y la bandera detrás de él podrían ser más adecuados para la pantalla de una laptop.

Evité deliberadamente este tema de "dirección artística" para enfocarme solo en imágenes con valores altos de DPI. Este problema se puede resolver con varios enfoques diferentes, como el uso de imágenes de fondo y consultas de medios, mediante JavaScript, con algunas funciones nuevas, como image-set, o en el servidor. Este tema se trata en Imágenes con altos DPI para densidades de píxeles variables.

Terminaré con algunos problemas abiertos:

  • Efectos de la compresión alta en el rendimiento ¿Cuáles son las penalizaciones de decodificar imágenes altamente comprimidas?
  • ¿Cuáles son las penalizaciones de rendimiento de tener que cambiar el tamaño de la imagen cuando se carga una imagen de 2x en una pantalla de 1x?

En resumen, opta por CSS y SVG en lugar de usar imágenes de trama. Si las imágenes de trama son estrictamente obligatorias, usa PNG para las imágenes con paletas limitadas y muchos colores sólidos, y JPEG para imágenes con muchos colores y gradientes. Lo bueno de este enfoque es que el lenguaje de marcado no cambia prácticamente. Lo único que debe hacer el desarrollador web es generar elementos el doble de elementos y ajustar el tamaño de tus imágenes correctamente en el DOM.

Para obtener más información, consulta el artículo de Scott Jehl sobre un tema similar. Que tus imágenes se vean nítidas y tu uso de datos móviles sea bajo.