Una motivación principal para el formato PNG era crear un reemplazo para GIF que no solo fuera gratuito sino también una mejora sobre él en todos los aspectos. Como resultado, la compresión PNG es completamente sin pérdidas, es decir, los datos de la imagen original se pueden reconstruir exactamente, bit por bit, al igual que en GIF y la mayoría de las formas de TIFF.
PNG utiliza un proceso de compresión de 2 etapas:
- Precompresión: filtrado (predicción)
- Compresión: DEFLATE (ver wikipedia )
El paso de precompresión se llama filtrado, que es un método de transformación reversible de los datos de imagen para que el motor de compresión principal pueda funcionar de manera más eficiente.
Como un ejemplo simple, considere una secuencia de bytes que aumenta uniformemente de 1 a 255:
1, 2, 3, 4, 5, .... 255
Como no hay repetición en la secuencia, se comprime muy mal o nada en absoluto. Pero una modificación trivial de la secuencia, es decir, dejar solo el primer byte pero reemplazar cada byte posterior por la diferencia entre él y su predecesor, transforma la secuencia en un conjunto extremadamente compresible:
1, 1, 1, 1, 1, .... 1
La transformación anterior no tiene pérdidas, ya que no se omitieron bytes, y es completamente reversible. El tamaño comprimido de esta serie se reducirá mucho, pero la serie original aún se puede reconstituir perfectamente.
Los datos de imagen reales rara vez son tan perfectos, pero el filtrado mejora la compresión en imágenes en escala de grises y color verdadero, y también puede ayudar en algunas imágenes de paleta. PNG admite cinco tipos de filtros, y un codificador puede elegir usar un filtro diferente para cada fila de píxeles en la imagen:
El algoritmo funciona en bytes, pero para los píxeles grandes (por ejemplo, RGB de 24 bits o RGBA de 64 bits) solo se comparan los bytes correspondientes, lo que significa que los componentes rojos de los colores de los píxeles se manejan por separado de los componentes de píxeles verdes y azules.
Para elegir el mejor filtro para cada fila, un codificador necesitaría probar todas las combinaciones posibles. Esto es claramente imposible, ya que incluso una imagen de 20 filas requeriría probar más de 95 billones de combinaciones, donde "probar" implicaría filtrar y comprimir toda la imagen.
Los niveles de compresión normalmente se definen como números entre 0 (ninguno) y 9 (mejor). Estos se refieren a compensaciones entre velocidad y tamaño, y se relacionan con cuántas combinaciones de filtros de fila se deben probar. No existen estándares con respecto a estos niveles de compresión, por lo que cada editor de imágenes puede tener sus propios algoritmos sobre cuántos filtros probar al optimizar el tamaño de la imagen.
El nivel de compresión 0 significa que los filtros no se utilizan en absoluto, lo cual es rápido pero derrochador. Los niveles más altos significan que se prueban más y más combinaciones en las filas de imágenes y solo se retienen las mejores.
Supongo que el enfoque más simple para la mejor compresión es comprimir de forma incremental cada fila con cada filtro, guardar el resultado más pequeño y repetir para la siguiente fila. Esto equivale a filtrar y comprimir la imagen completa cinco veces, lo que puede ser una compensación razonable para una imagen que se transmitirá y decodificará muchas veces. Los valores de compresión más bajos harán menos, a discreción del desarrollador de la herramienta.
Además de los filtros, el nivel de compresión también puede afectar el nivel de compresión zlib, que es un número entre 0 (sin desinflar) y 9 (desinflar máximo). La forma en que los niveles 0-9 especificados afectan el uso de los filtros, que son la principal característica de optimización de PNG, aún depende del desarrollador de la herramienta.
La conclusión es que PNG tiene un parámetro de compresión que puede reducir el tamaño del archivo de manera muy significativa, todo sin perder ni un solo píxel.
Fuentes:
Documentación de Wikipedia Portable Network Graphics
libpng Capítulo 9 - Compresión y filtrado