¡Hola de nuevo! Encontré este artículo escrito en mayo de 2019. Esta es la continuación de una serie de artículos sobre WAVE y JPEG, aquí. Esta publicación incluirá información sobre el algoritmo de codificación de imágenes y sobre el formato en sí.
Un poco de historia
Una cucharada de artículo de Wikipedia:
JPEG (Grupo Conjunto de Expertos en Fotografía) es uno de los formatos gráficos rasterizados más populares, utilizado para almacenar fotografías e imágenes similares.
Este estándar fue desarrollado por un grupo conjunto de expertos en fotografía en 1991 para la compresión eficiente de imágenes.
¿Qué camino recorren las imágenes desde su estado raw hasta JPEG?
Algunos creen que las imágenes JPEG son datos crudos comprimidos mediante Huffman, pero eso no es cierto. Antes de la compresión final, los datos pasan por un largo proceso.
Primero, se cambia el modelo de color de RGB a YCbCr. Para esto, incluso hay un algoritmo especial— . No se toca Y, ya que es responsable del brillo, y su modificación sería notable.
Lo primero que se hace con la imagen es «submuestreo» (subsampling). Es fácil de entender: se toma un bloque de 2x2 píxeles, luego se obtienen Cb y Cr: los valores promedio de cada uno de los componentes YCbCr de estos 4 píxeles. Y así, hemos ahorrado 6 bytes, en lugar de 4 Y, 4 Cb, 4 Cr, obtuvimos 4 Y y los mismos para cada uno de ellos Cb y Cr (4 + 4 + 4 = 12; 4 + 1 + 1 = 6; 12 - 6 = 6). En escala incluso 2x2, una compresión con pérdida con una relación de compresión de 2:1 suena sólida. Esto se aplica a toda la imagen. Así que hemos reducido a la mitad el tamaño. Y este truco se puede usar gracias a nuestra percepción del color. Una persona notará fácilmente la diferencia en brillo, pero no en color, si se promedia en un pequeño bloque de píxeles. El submuestreo también puede realizarse en línea, 4 píxeles horizontal y verticalmente. El primer método se usa más a menudo. Si la calidad de la imagen es importante, entonces el submuestreo no se realiza en absoluto.
Una ilustración visual del submuestreo (Habr no permitió insertar el gif) —
La parte principal de la preparación
DCT
Ahora viene la parte más complicada y necesaria. La imagen se divide en bloques de 8x8 (se utiliza un relleno si la resolución no es múltiplo del lado del bloque).
Ahora se aplica a cada bloque DCT (Transformada Discreta de Coseno)En esta parte se retira todo lo innecesario de la imagen. Usando DCT, es necesario entender si este bloque (8×8) describe alguna parte monótona de la imagen: el cielo, la pared; o si contiene una estructura compleja (cabello, símbolos, etc.). Es lógico que 64 píxeles similares en color pueden ser descritos por uno solo, ya que el tamaño del bloque ya es conocido. Así es como se logra la compresión: 64 a 1.
La DCT convierte el bloque en un espectro, y donde las lecturas cambian drásticamente, el coeficiente se vuelve positivo, y cuanto más brusco sea el cambio, mayor será la salida. Donde el coeficiente es más alto, la imagen presenta transiciones nítidas en color y brillo, donde es más bajo, cambios débiles (suaves) en los valores de los componentes YCbCr en el bloque.
Cuantización
Aquí ya se aplican ajustes de compresión. Cada uno de los coeficientes en cada una de las matrices 8×8 se divide por un número determinado. Si no va a reducir más la calidad de la imagen tras todas sus modificaciones, el divisor debe ser uno. Si le importa más la memoria ocupada por esta fotografía, entonces el divisor será mayor que 1, y el cociente se redondea. Así que a menudo, tras el redondeo, termina habiendo muchos ceros.
La cuantización se realiza para crear la posibilidad de una mayor compresión. Así es como se ve en el ejemplo de cuantización del gráfico y = sin(x):

Compresión
Primero se recorre la matriz en zig-zag:

Obtenemos un array unidimensional con números. Vemos que hay muchos ceros, que se pueden eliminar. Para ello, en lugar de una secuencia de muchos ceros, escribimos un cero y después un número que indique cuántos hay en la secuencia. De esta forma, se puede reducir a 1/3 el tamaño total del array. Luego, simplemente se comprime este array utilizando el método de Huffman y se escribe en el archivo.
Dónde se utiliza
En todas partes. Al igual que PNG, JPEG se utiliza en cámaras fotográficas, sistemas operativos (como logotipos de empresas, iconos de aplicaciones, miniaturas) y en todos los ámbitos posibles donde se necesita almacenar imágenes de manera eficiente.
Salida
Actualmente, el conocimiento sobre JPEG es valioso solo con fines educativos, pues ya está integrado en todas partes y optimizado por grandes grupos de personas, pero el granito del conocimiento sigue siendo atractivo.
Fuentes
Fuente: habr.com
