En Google, buscamos constantemente formas de hacer que las páginas web se carguen más rápido. Una forma de hacerlo es reduciendo el tamaño de las imágenes web. Las imágenes representan hasta el 60%-65% de los bytes en la mayoría de las páginas web, y el tamaño de la página es un factor importante en el tiempo de renderización total. El tamaño de la página es especialmente importante para los dispositivos móviles, en los que las imágenes más pequeñas ahorran ancho de banda y duración de batería.
WebP es un nuevo formato de imagen desarrollado por Google y compatible con Chrome, Opera y Android que está optimizado para permitir imágenes más rápidas y pequeñas en la Web. Las imágenes WebP son aproximadamente un 30% más pequeñas en comparación con las imágenes PNG y JPEG con una calidad visual equivalente. Además, el formato de imagen WebP también tiene paridad de funciones con otros formatos. Es compatible con:
Compresión con pérdida: La compresión con pérdida se basa en la codificación de fotogramas clave VP8. VP8 es un formato de compresión de video creado por On2 Technologies como sucesor de los formatos VP6 y VP7.
Compresión sin pérdida: El equipo de WebP desarrolló el formato de compresión sin pérdida.
Transparencia: El canal alfa de 8 bits es útil para las imágenes gráficas. El canal alfa se puede usar junto con RGB con pérdida, una función que actualmente no está disponible con ningún otro formato.
Animación: Admite imágenes animadas en colores verdaderos.
Metadatos: Pueden tener metadatos EXIF y XMP (que usan las cámaras, por ejemplo).
Perfil de color: Puede tener un perfil ICC incorporado.
Debido a la mejor compresión de las imágenes y la compatibilidad con todas estas funciones, WebP puede ser un excelente reemplazo para la mayoría de los formatos de imagen: PNG, JPEG o GIF. Aún mejor, ¿sabías que WebP habilita nuevas oportunidades de optimización de imágenes, como la compatibilidad con imágenes con pérdida y transparencia? Así es. WebP es el navaja suiza de los formatos de imagen.
Entonces, ¿cómo se hace esta magia? Arremánguense y veamos qué hay debajo del capó.
WebP con pérdida
La compresión con pérdida de WebP usa la misma metodología que VP8 para predecir tramas (video). VP8 se basa en la predicción de bloques y, como cualquier códec basado en bloques, divide la trama en segmentos más pequeños llamados macrobloques.
Dentro de cada macrobloque, el codificador puede predecir información de movimiento y color redundante según bloques procesados anteriormente. El fotograma de la imagen es “clave” en el sentido de que solo usa los píxeles que ya se decodificaron en el entorno espacial inmediato de cada uno de los macrobloques y trata de completar la parte desconocida de ellos. Esto se denomina codificación predictiva (consulta la codificación intrafotogramas del video VP8).
Luego, los datos redundantes se pueden restar del bloque, lo que genera una compresión más eficiente. Solo nos queda una pequeña diferencia, llamada residual, para transmitir en forma comprimida.
Después de estar sujetos a una transformación matemáticamente invertible (la famosa DCT, que significa transformación discreta del coseno), los residuales suelen contener muchos valores cero, que se pueden comprimir de manera mucho más eficaz. Luego, el resultado se cuantifica y se codifica con entropía. Curiosamente, el paso de cuantización es el único en el que se descartan los bits con pérdida (busca la división por QPj en el siguiente diagrama). Todos los demás pasos son reversibles y sin pérdidas.
En el siguiente diagrama, se muestran los pasos que se siguen en la compresión con pérdida de WebP. Las características diferenciadoras en comparación con JPEG están en círculo rojo.
WebP usa la cuantificación de bloques y distribuye los bits de forma adaptativa en diferentes segmentos de imagen: menos bits para segmentos de baja entropía y más bits para segmentos de entropía más alta. WebP usa la codificación de entropía aritmética, lo que logra una mejor compresión en comparación con la codificación de Huffman que se usa en JPEG.
Modos de predicción intraframe de VP8
Los modos de predicción intra de VP8 se usan con tres tipos de macrobloques:
- Luma 4 × 4
- Luma de 16 × 16
- Croma de 8 × 8
Estos macrobloques comparten cuatro modos de predicción intra:
H_PRED (predicción horizontal). Llena cada columna del bloque con una copia de la columna izquierda, L.
V_PRED (predicción vertical). Llena cada fila del bloque con una copia de la fila anterior, A.
DC_PRED (predicción de DC). Llena el bloque con un solo valor usando el promedio de los píxeles de la fila sobre A y la columna a la izquierda de L.
TM_PRED (predicción de TrueMotion). Es un modo que obtiene su nombre de una técnica de compresión desarrollada por On2 Technologies. Además de la fila A y la columna L, TM_PRED usa el píxel P arriba y a la izquierda del bloque. Las diferencias horizontales entre los píxeles de A (a partir de P) se propagan con los píxeles de L para iniciar cada fila.
En el siguiente diagrama, se ilustran los diferentes modos de predicción que se usan en la compresión con pérdida de WebP.
Para los bloques de luma de 4 × 4, hay seis modos intra adicionales similares a V_PRED y H_PRED, pero que corresponden a la predicción de píxeles en diferentes direcciones. Puedes encontrar más detalles sobre estos modos en la Guía de flujos de bits de VP8.
Cuadratura de bloques adaptable
Para mejorar la calidad de una imagen, esta se segmenta en áreas que tienen características visualmente similares. Para cada uno de estos segmentos, los parámetros de compresión (pasos de cuantificación, intensidad de filtrado, etc.) se ajustan de forma independiente. Esto genera una compresión eficiente redistribuyendo los bits donde son más útiles. VP8 permite un máximo de cuatro segmentos (una limitación del flujo de bits de VP8).
Por qué WebP (con pérdida) es mejor que JPEG
La codificación de predicción es una de las principales razones por las que WebP supera a JPEG. La cuantificación adaptativa por bloques también marca una gran diferencia. El filtrado ayuda con las tasas de bits medias o bajas. La codificación aritmética booleana proporciona entre un 5% y un 10% de ganancias de compresión en comparación con la codificación de Huffman.
WebP sin pérdida
La codificación sin pérdidas de WebP se basa en transformar la imagen con varias técnicas diferentes. Luego, se realiza la codificación de entropía en los parámetros de transformación y los datos de imagen transformados. Las transformaciones aplicadas a la imagen incluyen la predicción espacial de píxeles, la transformación del espacio de color, el uso de paletas emergentes locales, el empaquetado de varios píxeles en uno y el reemplazo de alfa. Para la codificación de entropía, usamos una variante de la codificación LZ77-Huffman, que usa codificación 2D de valores de distancia y valores dispersos compactos.
Transformación del predictor (espacial)
La predicción espacial se usa para reducir la entropía aprovechando el hecho de que los píxeles vecinos suelen estar correlacionados. En la transformación del predictor, el valor de píxel actual se predice a partir de los píxeles que ya se decodificaron (en orden de línea de exploración) y solo se codifica el valor residual (real - predicho). El modo de predicción determina el tipo de predicción que se usará. La imagen se divide en varias regiones cuadradas y todos los píxeles de un cuadrado usan el mismo modo de predicción.
Existen 13 modos de predicción diferentes. Los más comunes son los píxeles de la izquierda, la parte superior, la parte superior izquierda y la parte superior derecha. Los restantes son combinaciones (promedios) de izquierda, arriba, arriba a la izquierda y arriba a la derecha.
Transformación de color (descorrelación)
El objetivo de la transformación de color es decorrelar los valores de R, G y B de cada píxel. La transformación de color mantiene el valor verde (G) tal como está, transforma el rojo (R) según el verde y transforma el azul (B) según el verde y, luego, según el rojo.
Al igual que en el caso de la transformación del predictor, primero se divide la imagen en bloques y se usa el mismo modo de transformación para todos los píxeles de un bloque. Para cada bloque, hay tres tipos de elementos de transformación de color: green_to_red, green_to_blue y red_to_blue.
Transformación Subtract Green
La "transformación de resta de verde" resta los valores verdes de los valores rojos y azules de cada píxel. Cuando esta transformación está presente, el decodificador debe agregar el valor verde al rojo y al azul. Este es un caso especial de la transformación general de decorrelación de colores anterior, lo suficientemente frecuente como para garantizar un corte.
Transformación de indexación de colores (paleta)
Si no hay muchos valores de píxeles únicos, puede ser más eficiente crear un array de índices de color y reemplazar los valores de píxeles por los índices del array. La transformación de indexación de colores logra esto. La transformación de indexación de colores verifica la cantidad de valores ARGB únicos en la imagen. Si ese número está por debajo de un umbral (256), se crea un array de esos valores ARGB, que luego se usa para reemplazar los valores de píxeles por el índice correspondiente.
Codificación de la caché de colores
La compresión WebP sin pérdida usa fragmentos de imágenes ya vistos para reconstruir píxeles nuevos. También puede usar una paleta local si no se encuentra una coincidencia interesante. Esta paleta se actualiza de forma continua para volver a usar los colores recientes. En la siguiente imagen, puedes ver la caché de colores local en acción, que se actualiza de forma progresiva con los 32 colores usados recientemente a medida que el análisis se desplaza hacia abajo.
Referencia de compatibilidad con versiones anteriores de LZ77
Las referencias hacia atrás son tuplas de código de longitud y distancia. La longitud indica cuántos píxeles en orden de línea de exploración se deben copiar. El código de distancia es un número que indica la posición de un píxel visto anteriormente, desde el que se copiarán los píxeles. Los valores de longitud y distancia se almacenan con codificación de prefijo LZ77.
La codificación de prefijos LZ77 divide los valores de números enteros grandes en dos partes: el código de prefijo y los bits adicionales. El código de prefijo se almacena con un código de entropía, mientras que los bits adicionales se almacenan tal como están (sin un código de entropía).
En el siguiente diagrama, se ilustra el LZ77 (variante 2D) con coincidencia de palabras (en lugar de píxeles).
WebP con pérdida y alfa
Además del WebP con pérdida (colores RGB) y el WebP sin pérdida (RGB sin pérdida con alfa), existe otro modo de WebP que permite la codificación con pérdida para los canales RGB y la codificación sin pérdida para el canal alfa. Por el momento, esa posibilidad (RGB con pérdida y alfa sin pérdida) no está disponible con ninguno de los formatos de imagen existentes. Actualmente, los webmasters que necesitan transparencia deben codificar las imágenes sin pérdida en PNG, lo que genera un aumento significativo de tamaño. WebP alpha codifica imágenes con pocos bits por píxel y proporciona una forma eficaz de reducir el tamaño de esas imágenes. La compresión sin pérdida del canal alfa agrega solo 22% de bytes en comparación con la codificación WebP con pérdida (calidad 90).
En general, reemplazar un PNG transparente por un WebP con pérdida y alfa genera un ahorro de tamaño de entre el 60 y el 70% en promedio. Esto se confirmó como una gran característica atractiva para los sitios móviles con muchos íconos (por ejemplo, everything.me).