Cómo reducir los tamaños de descarga de imágenes

La mayoría del tráfico de descarga consta de imágenes. En consecuencia, cuanto más pequeñas sean las imágenes para descargar, mejor será la experiencia de red que tu app ofrezca a los usuarios. En esta página, se proporcionan instrucciones para reducir el tamaño de los archivos de imagen y optimizarlos para la red.

Acerca de los formatos de imagen

Las apps para Android suelen usar imágenes con uno o más de los siguientes formatos de archivo: PNG, JPG y WebP. Para cada formato, puedes seguir ciertos pasos a fin de reducir los tamaños de imagen.

PNG

Una clave para hacer que tus archivos PNG sean más pequeños es reducir la cantidad de colores únicos utilizados en cada fila de píxeles de la imagen. Si usas menos colores, mejorarás el potencial de compresión en todas las otras etapas de la canalización.

Reducir la cantidad de colores únicos genera una gran diferencia, ya que la eficacia de la compresión de PNG depende, en parte, del grado de variación de los píxeles horizontales adyacentes. Por lo tanto, reducir la cantidad de colores únicos en cada fila de tus imágenes PNG puede ayudar a reducir el tamaño de los archivos.

Cuando decidas si deseas aplicar esta estrategia, debes tener en cuenta que reducir la cantidad de colores únicos equivale a aplicar a la imagen una etapa de codificación con pérdida. Sin embargo, es posible que una herramienta de codificación no sea la mejor manera de determinar cuán grave es para el ojo humano un error aparentemente pequeño. Por lo tanto, debes realizar este trabajo de forma manual para ayudar a garantizar el equilibrio adecuado entre una compresión eficaz y una calidad de imagen aceptable.

Existen dos enfoques particularmente útiles que puedes tomar: esforzarte por usar formatos indexados o aplicar la cuantización vectorial.

Cómo usar formatos indexados

Cualquier intento de reducción de color debe comenzar con el intento de optimizar los colores a fin de poder usar el formato INDEXADO para exportar la imagen como PNG. El modo de color INDEXADO funciona eligiendo los mejores 256 colores y reemplazando todos los valores de píxeles con índices de esa paleta de colores. El resultado es una reducción de 16 millones de colores (potenciales) a solo 256 colores: de 3 (sin transparencia) o 4 (con transparencia) bytes por píxel a 1 byte por píxel. Este cambio es un primer paso importante de la reducción del tamaño del archivo.

En la figura 1, se muestra una imagen y su variante indexada.

Figura 1: Una imagen antes y después de la conversión al formato INDEXADO

En la figura 2, se muestra la paleta de colores para la imagen de la figura 1:

Figura 2: La paleta de colores para la imagen de la figura 1

Representar la imagen como una imagen con paleta ayuda mucho a mejorar en gran medida el tamaño del archivo, por lo que vale la pena investigar si es posible convertir la mayoría de las imágenes.

Por supuesto, no todas las imágenes se pueden representar con precisión con solo 256 colores. Por ejemplo, algunas imágenes pueden necesitar 257, 310, 512 o 912 colores para tener un aspecto correcto. En estos casos, la cuantización vectorial también puede ser útil.

Cuantización vectorial

El proceso de creación de una imagen indexada puede describirse con más precisión como cuantización vectorial (VQ). La VQ sirve como proceso de redondeo para números multidimensionales. En este proceso, todos los colores de tu imagen se agrupan según su similitud. Para un grupo determinado, se reemplazan todos los colores de ese grupo por un único valor de punto central, que minimiza el error relacionado con los colores en esa celda (o "sitio", si usas la terminología de Voronoi). En la figura 3, los puntos verdes representan los colores de entrada y los puntos rojos son los puntos centrales que reemplazan los colores de entrada. Cada celda está delimitada por líneas azules.

Figura 3: Aplicación de la cuantización vectorial a los colores de una imagen

Con la aplicación de la VQ a una imagen, se reduce la cantidad de colores únicos y se reemplaza cada grupo de colores por un solo color "bastante cercano" en calidad visual.

Esta técnica también te permite definir la cantidad máxima de colores únicos en tu imagen. Por ejemplo, en la figura 4, se muestra una cabeza de loro en 16.7 millones de colores (24 bits por píxel o bpp), junto a una versión que solo permite 16 colores únicos (3 bpp).

Figura 4: Imagen de antes y después de la aplicación de la cuantización vectorial

A simple vista, puedes ver que hay una pérdida de calidad. Se reemplazó la mayoría de los colores de la gradiente, lo que produjo un efecto de bandas en la imagen. Esta imagen necesita más de 16 colores únicos.

Configurar un paso de VQ en la canalización puede ayudarte a tener una mejor idea de la cantidad real de colores únicos que usa tu imagen, además de ayudarte a reducirlos en gran medida. Existen varias herramientas disponibles que puedes usar para implementar esta técnica.

JPG

Si estás utilizando imágenes JPG, puedes hacer varios cambios pequeños que te pueden ayudar a reducir en gran medida el tamaño del archivo. Por ejemplo:

  • Producir un tamaño de archivo más pequeño a través de diferentes métodos de codificación (sin afectar la calidad).
  • Ajustar levemente la calidad para obtener una mejor compresión.

Por lo general, si sigues estas estrategias, puedes obtener reducciones de tamaño de archivo de hasta un 25%.

Cuando elijas las herramientas, recuerda que las de exportación de fotos pueden insertar en las imágenes metadatos innecesarios, como información de GPS. Como mínimo, intenta aprovechar las herramientas existentes para ayudar a quitar esta información de tus archivos.

WebP

WebP es un formato de imagen más nuevo, compatible con Android 4.2.1 (API nivel 17). Este formato proporciona una compresión sin pérdidas y con pérdidas superior para imágenes de la Web. Con WebP, los programadores pueden crear imágenes más pequeñas y enriquecidas. Los archivos de imagen WebP sin pérdida son, en promedio, un 26% más pequeños que los PNG. Estos archivos de imagen también admiten transparencia (también conocida como canal alfa) a un costo de solo un 22% más de bytes.

Las imágenes WebP con pérdida son entre un 25% y un 34% más pequeñas que las imágenes JPG comparables con índices de calidad SSIM equivalentes. Para los casos en que la compresión RGB con pérdida es aceptable, el formato WebP con pérdida también admite transparencia y, por lo general, produce tamaños de archivo 3 veces más pequeños que PNG.

Para obtener más información sobre WebP, visita el sitio web de WebP.

Con Android Studio, puedes convertir imágenes GIF estáticas o BMP, JPG o PNG ya existentes a formato WebP. Para obtener más información, consulta Cómo crear imágenes WebP con Android Studio.

Cómo seleccionar un formato

Los diferentes formatos de imagen son adecuados para los diferentes tipos de imágenes. JPG y PNG tienen procesos de compresión muy distintos y producen resultados bastante diferentes.

Por lo general, la decisión entre PNG y JPG se reduce a la complejidad de la imagen. En la figura 5, se muestran dos imágenes que aparecen de manera bastante diferente según el esquema de compresión que aplique el desarrollador. La imagen de la izquierda tiene muchos pequeños detalles y, por lo tanto, se comprime de manera más eficiente con JPG. La imagen de la derecha, con bandas del mismo color, se comprime de manera más eficiente con PNG.

Figura 5: Casos adecuados de JPG vs. PNG

WebP como formato puede admitir modos con y sin pérdida, por lo que es un reemplazo ideal tanto para PNG como para JPG. Lo único que debes tener en cuenta es que solo cuenta con asistencia nativa en dispositivos con Android 4.2.1 (API nivel 17) o versiones posteriores. Por suerte, la gran mayoría de los dispositivos cumple con ese requisito.

En la figura 6, se proporciona una visualización simple para ayudarte a decidir qué esquema de compresión debes usar.

Figura 6: Cómo decidir qué esquema de compresión debes usar

Cómo determinar valores de calidad óptima

Existen varias técnicas que puedes usar para lograr el equilibrio correcto entre la compresión y la calidad de la imagen. Una técnica utiliza valores escalares y, por lo tanto, solo funciona para JPG y WebP. La otra técnica aprovecha la biblioteca Butteraugli y se puede usar con todos los formatos de imagen.

Valores escalares (solo JPG y WebP)

Las ventajas de los formatos JPG y WebP provienen del hecho de que puedes usar un valor escalar para equilibrar la calidad con el tamaño del archivo. El truco está en descubrir cuál es el valor de calidad correcto para la imagen. Un nivel de calidad demasiado bajo produce un archivo pequeño, en el que se pierde la calidad de la imagen. Un nivel de calidad demasiado alto aumenta el tamaño del archivo sin proporcionar un beneficio notable al usuario.

La solución más directa es elegir un valor no máximo y usar ese valor. Sin embargo, ten en cuenta que el valor de calidad afecta a cada imagen de manera diferente. Si bien una calidad del 75%, por ejemplo, puede hacer que la mayoría de las imágenes tengan un buen aspecto, es posible que en algunos casos no funcione tan bien. Debes asegurarte de probar el valor máximo elegido con una muestra representativa de imágenes. Además, asegúrate de realizar todas las pruebas con las imágenes originales y no con las versiones comprimidas.

Para las apps de medios grandes que suben y reenvían millones de archivos JPG por día, no es práctico realizar ajustes manuales en cada elemento. Puedes abordar este desafío especificando varios niveles de calidad diferentes según la categoría de la imagen. Por ejemplo, puedes establecer el 35% como la configuración de calidad para las miniaturas, ya que una imagen más pequeña oculta más artefactos de compresión.

Butteraugli

El proyecto Butteraugli es una biblioteca que sirve para probar el umbral de error psicovisual de una imagen: el punto en el que la persona que mira comienza a notar la degradación de la imagen. En otras palabras, este proyecto intenta cuantificar la distorsión de la imagen comprimida.

Butteraugli te permite definir un objetivo para la calidad visual y, luego, ejecutar compresiones PNG, JPG, WebP con pérdida y WebP sin pérdida. A continuación, puedes elegir la imagen que tenga el mejor equilibrio entre el tamaño del archivo y el nivel de Butteraugli. En la figura 7, se muestra un ejemplo de cómo se usó Butteraugli para encontrar el nivel mínimo de calidad de JPG antes de que la distorsión visual fuera lo suficientemente alta para que un usuario pudiera percibir un problema. El resultado es una reducción de aproximadamente el 65% en el tamaño del archivo.

Figura 7: Una imagen antes y después de la aplicación de la tecnología de Butteraugli

Butteraugli te permite trabajar en función de la salida o la entrada. Es decir, puedes buscar la configuración de calidad más baja antes de que el usuario perciba una distorsión notable en la imagen resultante. También puedes establecer niveles de distorsión de imagen de manera iterativa para conocer los niveles de calidad asociados.

Tamaños de entrega

Es tentador mantener solo una resolución única de una imagen en un servidor. Cuando un dispositivo accede a la imagen, el servidor la pasa a esa resolución y deja la tarea de reducción de escala al dispositivo.

Esta solución es conveniente para el desarrollador, pero puede ser incómoda para el usuario, ya que lo obliga a descargar muchos más datos de los que necesita. En cambio, debes almacenar varios tamaños de imágenes y entregar el tamaño que sea más apropiado para un caso práctico específico. Por ejemplo, en el caso de una miniatura, entregar una real en lugar de entregar y reducir una versión de tamaño completo consume mucho menos ancho de banda de red.

Este enfoque es útil para obtener una buena velocidad de descarga y es menos costoso para los usuarios, que tal vez estén usando planes de datos medidos o limitados. Este método también hace que la imagen ocupe menos espacio en el dispositivo y en la memoria principal. En el caso de imágenes grandes, como las 4K, este enfoque también evita que el dispositivo tenga que cambiar el tamaño de las imágenes antes de subirlas.

La implementación de este enfoque requiere que tengas un servicio de imágenes de backend para proporcionar imágenes en varias resoluciones con el almacenamiento en caché adecuado. Existen servicios existentes que pueden proporcionar ayuda en relación con esta tarea. Por ejemplo, App Engine incluye la funcionalidad de cambio de tamaño de imagen ya instalada.