Imágenes como cajas: ¿qué hay dentro? Informar en Yandex

Las imágenes y los videos son "cajas negras", dentro de las cuales hay muchas cosas interesantes e incomprensibles. Pero puede mirar dentro de algunos formatos, cambiar todo allí y ver qué sucede.

Polina Gurtovaya, de la compañía Evil Martians, habló en nuestra conferencia  Frontend en febrero. Con la ayuda del experimento, Polina descubrió cómo convertir imágenes simples en "imágenes efectivas" con métricas. Las herramientas que pueden hacer esto por nosotros, Polina examinó más cerca del final del informe. El resultado fue una gran excursión al interior y a los principios de funcionamiento de varios formatos: desde PNG y JPEG hasta AV1 y exóticos.


- Hola a todos. Mi nombre es Polina, soy el frente de la empresa "Evil Martians".

Tal vez conoces marcianos de nuestras muchas fuentes abiertas. Te contaré un poco sobre él más tarde. Y probablemente debo decir que todavía estamos desarrollando productos, y no solo aserrando código abierto.



Los materiales para el informe estarán disponibles para usted a través de un maravilloso enlace en el repositorio en GitHub.



Hablemos un poco sobre la optimización. Cuando tratamos con ellos, el problema es que funcionan bien si entendemos lo que estamos haciendo. Si no entendemos, resulta mal. Cuando se trata de la optimización de imágenes, desafortunadamente, todo aquí no es realmente genial. Es posible que no optimicemos las imágenes en absoluto, y luego habrá monstruos de dos metros en el producto, todo es triste y triste.

Si optimizamos, ¿qué estamos haciendo? Pensamos: aquí tenemos una imagen, es una especie de misteriosa caja negra, y el programa optimizador hace algo con esta imagen, una especie de chamanismo negro. La calidad de optimización que obtenemos es un poco dudosa.



Veamos un ejemplo. Tengo un gato en formato PNG. Creo que necesitamos optimizarlo. ¿Qué estoy haciendo? Creo una versión de WebP y pongo cuidadosamente ambas imágenes en una etiqueta <picture>. ¿Crees que he terminado bien aquí o no? ¿Por qué hay tan pocas manos? Estoy muy bien hecho!

Hice todo bien, pero la versión de WebP resultó dos kilobytes más que la original. Esto es un poco no lo que quería.




Otra optimización, intento número 2. Tengo un pequeño contenedor en la página y un gran gato grande. Quiero poner un gato grande en un recipiente pequeño. ¿Qué estoy haciendo? Estoy haciendo un cambio de tamaño porque es estúpido conducir bytes a través de la red si el tamaño de mi contenedor es pequeño. Por supuesto, tengo en cuenta la relación de píxeles del dispositivo de mi dispositivo. ¿Crees que estoy bien aquí o no? ¡He terminado! Y mira lo que hice.

Estoy usando la biblioteca libvips. Ella es muy genial y popular, y de mi enorme pero feliz gato ligero obtuve un gato pequeño y muy pesado. El sello aumentó 2.5 veces (en bytes) durante el cambio de tamaño (en píxeles) hacia abajo. Genial, si?



En general, para que esto no nos suceda, que comprendamos cómo optimizar nuestras imágenes para nuestra tarea, y, en general, para que al menos comprendamos lo que está sucediendo, echemos un vistazo a la caja y comprendamos qué hay dentro.



Comencemos mirando un formato tan interesante como PNG. Alrededor de cada sitio, un pequeño peengshechka está escondido en alguna parte. Esta vez. Por lo tanto, deben ser entendidos. Segundo: PNG: formato de compresión sin pérdidas. Esto significa que garantizamos una coincidencia perfecta con el original en píxeles, pero al mismo tiempo, por desgracia, estamos limitados por naturaleza, no podemos comprimir menos de cuánto.



Peengeshka se pliega en un contenedor, como cualquier formato de imagen. Una de las primeras cosas que debemos decirle al programa si lo lee todo es lo que hay dentro. Si supone que sus decodificadores determinan las imágenes por extensión, esto no es así.

Pengashka informa que es PNG, los primeros ocho bytes en su contenedor. Dice "PNG". Además, una vez más, esto es característico de cualquier contenedor: tiene un diseño de trozos. Es decir, la información está empaquetada en trozos, de alguna manera están organizados. Cómo: define el contenedor. En PNG, se ve así: tiene cuatro bytes que son responsables de la longitud y cuatro bytes que son responsables del tipo de fragmento. Qué tipos: hablaremos un poco más tarde. 

Si el fragmento tiene una longitud distinta de cero, tiene una carga útil. Además, existe una suma de comprobación. Estás comprobando si algo ha sido golpeado allí. Luego vienen los siguientes fragmentos.



Analizar no solo un archivo PNG, sino que casi cualquiera es bastante fácil. Tome FileReader, esta es una API de navegador. Leemos el archivo usando FileReader. Tan pronto como leemos, cortamos este archivo en trozos. No daré aquí el código de la función de división en fragmentos, pero puedes adivinar que hay una combinación intrincada de if y for. 




Bien, lo hemos cortado, veremos qué pasa. Tenemos varios tipos de fragmentos, y son muy, muy característicos de casi cualquier formato. El primero se llama IHDR. Hay una serie de fragmentos llamados IDAT. Estos nombres pueden parecerle un poco extraños, pero ahora descubriremos de qué se trata. Cuando todo termina, vemos el trozo final.



Echemos un vistazo más de cerca dentro de los trozos. IHDR es un meta-fragmento, y casi cualquier imagen tiene dicho meta-fragmento. Se llama de manera diferente, se organiza de manera diferente, pero lo más probable es que lo sea. Sin él, su descompresor, algo que le muestra peengeshki o no peengeshki, no puede mostrarle nada. ¿Qué hay en este pedazo? Nuevamente, el contenido es típico para la mayoría de los formatos. Esta es la altura y el ancho. La altura y el ancho están cosidos en su archivo, se trata de usted. Los siguientes son los típicos indicadores de estilo: bitDepth, colorType y entrelazado. 



Antes de hablar sobre lo que significan estas banderas y por qué son tan, muy importantes para nosotros, veamos cómo almacenamos píxeles en pangshes. En peaneshs, los píxeles se almacenan dentro de un fragmento llamado IDAT. En un buen escenario, los píxeles son una cierta cantidad de números que se empaquetan en un fragmento, y este fragmento se comprime mediante el algoritmo de compresión Deflate. ¿Quién usó el algoritmo de compresión Deflate? Bien, ¿cuándo fue la última vez que comprimiste algo? ¿Sabes que Deflate es gzip? Así que creo que muchos lo usaron.

Pero en peengeshah aparece otra cosa interesante que se usa en una gran cantidad de formatos, pero probablemente en todos. Este artilugio se llama codificación predictiva. El hecho es que nuestras imágenes no son píxeles aleatorios. Lo que está pintado en nuestra pequeña imagen está de alguna manera conectado entre sí. Hay algunas áreas oscuras, áreas brillantes, etc.

Estamos tratando de explotar este hecho, y en lugar de almacenar el valor de píxel en estas celdas azules, estamos tratando de predecir estos píxeles en función de los anteriores. En PNG, estas predicciones son muy simples y se empaquetan en el primer byte antes de la línea con píxeles. Una predicción puede ser así, por ejemplo, no pronostiquemos nada y simplemente pongamos todo como está. O, por ejemplo, podemos decir esto: pero solo mantengamos la diferencia entre el píxel actual y el anterior.

Si tiene el mismo color en su línea, tendrá todos los ceros, todo está perfectamente comprimido, esto es muy bueno.



Pero ahora hablemos de lo que realmente significa un píxel. Un píxel aparece en un peengesh como un número de números. Al manipular cuántos números hay, puede comprimir muy, muy estrechamente su PNG, tres veces.

¿Qué opciones hay? El primero es True Color y alpha. Tenemos tres canales, tres colores, tres números por color. Además de un canal responsable de la transparencia.

El tamaño de este número en bits es bitDepth, el mismo indicador que vimos en el fragmento IHDR. Cuanto más pequeño sea su bitDepth, más pequeño será el archivo, pero menos colores podrá presentarles. Un número típico es 8. ¿Cuánto es? En mi opinión, habrá 16 millones con algo.

De acuerdo, la primera optimización que puedes hacer es tirar los canales alfa en tu peengesh. Este será un colorType diferente.

Puede optimizar aún mejor y usar solo uno en lugar de cuatro números. Pero el problema es que tu peengeshka debería ser blanco y negro.

Si todavía desea solo un número y deja los colores, entonces esto también se puede hacer. ¿Que está pasando aqui? Tomas todos los colores dentro de tu peengeshka y los cortas en un trozo separado. Llámalo paleta. Más adentro de la muestra, que es responsable del píxel dentro del fragmento IDAT, simplemente almacena el índice de esta paleta. Si tiene alguna captura de pantalla sin un fondo intrincado o algún dibujo, esto es perfecto. Ella aprieta peengeshki ¡guau!

Otra cosa importante que decir es sobre el entrelazado. ¿Qué es el entrelazado? Esto es cuando envías tu peengeshka gradualmente. No tienes una peengeshka, sino varias imágenes. Cada imagen se llama escaneo.



Al mismo tiempo, dentro del paengashka, clasifica los píxeles de tal manera que algunos de los píxeles se separan de las imágenes, una imagen proviene de lugares especiales. La siguiente parte es otra y así sucesivamente. Una técnica aparentemente genial como JPEG progresivo.

Pero se ve así. No estoy seguro si desea que sus usuarios vean esto, aunque puede ser útil para su tarea.

El segundo y muy grave problema de PNG entrelazado es que tan pronto como entrelazas tu peengeshka, el tamaño de tu peengeshka se hace más grande. Y ya no tan débil, en algún lugar en un par de kilobytes, tu peengeshka de seis kilobytes crecerá si desactivas Interlaced. Por lo tanto, piense detenidamente si lo quiere o no.



Hablamos solo de PNG, pero de esto puedes sacar conclusiones importantes y útiles. Primera conclusión: el tamaño de su archivo, no lo creerá, depende de lo que se dibuje allí. El cuadrado negro se contrae mejor que el gato, no daré ninguna recomendación aquí. Segundo, más importante: el tamaño de su archivo depende mucho del codificador y de los parámetros que transfiera.

Si quieres ver cómo funcionan los codificadores horribles, usa los del navegador. ¿Cómo está hecho? Tome el archivo PNG, dibújelo en el lienzo, luego haga clic en Guardar como y compare lo que sucedió con lo que sucedió. En general, Chrome aumentará el tamaño de su archivo en 2.5 veces, Firefox, en 1.6.

Por cierto, también siempre depende del formato, es decir, no solo se debe usar PNG. Comprendamos por qué todo depende del formato y de las opciones interesantes que aún tenemos.



Para hacer esto, hablaremos sobre la tecnología de los antiguos, sobre JPEG. Por supuesto, no puede minimizar la importancia de JPEG. Se encuentran en todas partes. Son tan geniales, buenos y aún más, los sellos en JPEG son una historia bastante común. Pero JPEG es algo bastante complicado, y es complicado debido al hecho de que JPEG es una compresión con pérdida. Además, JPEG siempre es una compresión con pérdida. JPEG 100% de calidad todavía se comprime con pérdida.

¿Cómo obtenemos compresión con pérdida? Muy simple. Tomamos alguna fuente, arrojamos los datos de ella y luego la comprimimos sin pérdida. Es decir, más un paso.



Veamos cómo hacemos pérdidas en nuestros archivos JPEG. Entonces, tienes un gato con un tamaño de 32 por 32. Para que podamos dar el primer paso con pérdidas, necesitamos cambiar nuestros canales. Por lo general, hablamos de imágenes en términos de RGB. Pero percibimos los colores un poco intrincados. Nuestro cerebro generalmente es un gran problema, aunque nos ayuda mucho a comprimir JPEG.

Percibimos muy bien el blanco y negro. Incluso si observa detenidamente, notará que los detalles en la imagen en blanco y negro se distinguen mejor. Acabamos de poner esta imagen en blanco y negro en un canal separado. Se llama Y. En realidad, la barra Y. No estamos haciendo nada con él, simplemente lo dejamos como está.

Hay dos canales más que son responsables del color. Estos son CB y CR. Con estos canales ya podemos divertirnos un poco. Aquí con estos canales producimos un procedimiento tan genial llamado Downsampling. Tomamos y reducimos la resolución de este canal. Para JPEG es típico reducir a la mitad. Es decir, de hecho, obtienes tres imágenes, una original y dos la mitad. ¡Hurra!

¿Qué hacemos a continuación? No comprimimos JPEG, no como un archivo completo. Lo dividimos en bloques y comprimimos aún más, ya estamos comenzando bloques. Los bloques en JPEG tienen un tamaño de 8 por 8 y observa qué les sucede. Veamos el canal Y. CB y CR son todos iguales.



Entonces, un bloque no es una imagen, sino números. Necesitamos hacer pérdidas en JPEG. Este bloque es de 8 por 8, 64 píxeles, ¿cuál tirar? ¿El de la izquierda, el de la derecha, el del medio? Poco claro. Pero hay matemáticas geniales que nos permiten resolver este problema.

Esta matemática se llama, ahora, por favor, no se ponga nervioso si alguien recuerda el terrible pasado institucional: la transformación discreta del coseno. Entonces, con la ayuda de esta transformada discreta del coseno, puede convertir estos números en su bloque para que sean importantes y sin importancia entre ellos.

Importante: después de la conversión, los números importantes permanecen en la parte superior izquierda del bloque. En la esquina inferior derecha quedan números sin importancia.

A continuación, debe realizar su pérdida de JPEG. Esto también es muy fácil de hacer. Este truco se llama cuantización. Lo siento si quieres dormir ahora, pero esto es importante, créeme. Entonces, esta misma cuantización funciona de una manera bastante simple. Tomas tu bloque y una placa especialmente diseñada. Esta placa está determinada por su programa de codificador. Esos números que resultaron en su bloque, los divide por este término de placa por número y número entero. ¿Qué obtienes como resultado?

Como los números son grandes en la parte inferior derecha de la placa, solo habrá ceros.



Y al mismo tiempo tu JPEG, tu bloque se comprimirá perfectamente. Tendrá una pequeña cantidad de números que evitará en un zigzag tan intrincado, todos los ceros desaparecerán y, gracias, nuestro bloque está listo para la compresión. Entonces solo necesitamos comprimirlo con un algoritmo de compresión sin pérdidas. JPEG usa Huffman Coding, sea lo que sea.



¿Cómo se empaca en un contenedor? Los contenedores JPEG se ven un poco tontos, les tengo miedo. Porque ves los primeros dos bytes y dice que lo más probable es que sea JPEG. Pero hasta ahora no está claro.

A continuación, debe buscar dos fragmentos de meta. ¿Por qué dos? Porque JPEG es un conjunto muy grande de diferentes estándares. Lo que llamamos JPEG es, por norma, llamado JIFF. Esta es una extensión especial del estándar JPEG. No continuaré más allá: en general, hay dos fragmentos de meta, solo confía en mí. Estos meta-fragmentos contienen información sobre el ancho y alto de su archivo y la versión de JPEG. ¡Imagínese, JPEG tiene más versiones! Y además, ¿es JPEG progresivo? Esta es una bandera importante. Habla sobre cómo se distribuirán más tus bloques.

Si JPEG no es progresivo, ¿qué necesitas para decodificar tus bloques? Calidad JPEG, esta misma placa. La placa en la que divide sus bloques es de calidad. Pero JPEG tiene dos cualidades. La primera calidad es responsable del canal Y, la segunda: para los canales CB y CR, esto es lo que determina el color. Como ponemos la calidad en un archivo y lo exprimimos todo con un algoritmo de compresión sin pérdidas, aún necesitamos un diccionario especial de tablas de Huffman para expandir esto.

Luego vienen tus bloques, y luego tu JPEG ha terminado.



De acuerdo, una historia progresiva. Todo es exactamente lo mismo. Al principio tienes un meta-fragmento. Luego viene su calidad en forma de 64 números, más 64 números. Y luego solo los mismos bloques, pero un poco diferentes con los números distribuidos. Primera parte de los bloques, luego otra parte, otra parte, etc. A medida que recibe estos bloques, el navegador dibuja una aproximación de su JPEG, porque, de hecho, estos números son una aproximación de su archivo.



Sobre JPEG que terminamos, puedes exhalar, todo está bien. Hablemos de algo tan interesante como JPEG 2000. ¿Alguno de ustedes en producción usa JPEG 2000? ¿Quién ha oído hablar de esto? ¿Y cuál de ustedes ha leído en Lighthouse: "utilizar formatos modernos"?

En general, JPEG 2000 es un formato interesante y genial, que, en primer lugar, es más efectivo que JPEG. En segundo lugar, no lo creerá, en algunos casos es más efectivo que WebP, del que hablaremos más adelante.

Sabe ser transparente, sabe comprimir sin pérdida. Solo el formato perfecto. Pero desafortunadamente, sí, solo funciona en Safari.

Vale la pena mencionar que JPEG 2000 está diseñado de una manera muy compleja y funciona en matemáticas geniales llamadas transformaciones wavelet. Si de repente te interesa, google, y iremos más allá.



Entonces, de repente, necesitamos hablar sobre el video. Todo este informe trata sobre la optimización de imágenes y sobre imágenes. Pero el video aquí es muy importante, verás por qué ahora. Cuando pensamos en un video, la primera palabra que nos viene a la mente es "códec". El video debe estar codificado de alguna manera, y para mostrarlo, debemos decodificarlo. Si decodificamos la transmisión de video, ¿qué obtenemos?

En primer lugar, tenemos un conjunto de marcos. Pero no piense en estos cuadros como imágenes en el GIF. Todo mal. Qué cuadros dependen mucho del códec. Pero en el caso general, puede suponer que tiene un fotograma clave. Puede sacar un gato del fotograma clave, en el sentido, cualquier imagen que esté en este fotograma clave. Y hay marcos dependientes. Es imposible sacar un gato del cuadro dependiente, porque el cuadro dependiente almacena no solo información no sobre la imagen, si la hay, sino sobre cómo se movieron los bloques del cuadro anterior o anterior. Por lo tanto, no puede obtener una imagen para un cuadro dependiente hasta que decodifique un poco.

Todo lo que vamos a hablar ahora es la compresión de fotogramas clave y dentro de fotogramas. Así es como se comprime una imagen dentro de un fotograma clave.

Veamos un códec abstracto en el vacío y compárelo con JPEG. Hasta ahora parece, ¿por qué hacer esto? Todo se aclarará, confía en mí.



Una vez más, repetimos lo mismo que hacemos con JPEG,. Toma una fotografía, la divide en canales, hace un muestreo descendente en los canales. La misma historia aquí. Luego rompes esta imagen en bloques. Pero ya hay características. En primer lugar, el tamaño del bloque en el que está entrando depende de su códec. Y estos bloques pueden ser muy grandes. Para JPEG - 8 por 8. Para códecs de video - puede ser, por ejemplo, 128 por 128.

Más lejos. Si obtiene algunos detalles muy pequeños sobre su imagen a los que desea prestar atención, aún puede subdividir los bloques un poco, aproximadamente al tamaño 4 por 4. Cómo rompe los bloques, este algoritmo de partición depende del códec.

Y lo más reciente: el tamaño máximo de bloque, nuevamente, es específico para su códec. Un codificador es parte del códec, que debe entenderse en terminología. Aquí todavía somos similares a JPEG.



Lo que no parece JPEG es la codificación predictiva. Hablamos de él en parte sobre peengeshki. La compresión de video dentro del marco es tan genial y efectiva solo por esto. ¿Que está pasando aqui?

Estamos tratando de predecir los píxeles de cada bloque en función de los anteriores. Es decir, no almacenamos píxeles en forma cruda, los predecimos. Las opciones de predicción son muchas. Dentro de un códec, podemos usar diferentes variantes de predicciones. Además, para todo tipo de códecs intrincados de estas opciones, hasta 35, por ejemplo. Cómo puedes hacer esto. Veamos un ejemplo.

Aquí tienes el bloque. Dices: Quiero predecir píxeles allí. Miras hacia la izquierda, miras hacia arriba y recuerdas lo que queda y arriba. Luego, toma todos los valores de píxeles que encontró, promedia y lo llena con un bloque, y dice: Predije. Si acertó y, por cierto, en la pequeña imagen donde hay flechas azules, acertó, entonces es genial, no tiene que hacer nada más. Pero, si no lo ha adivinado, debe guardar la diferencia entre lo que realmente es y lo que predijo. Esta diferencia se comprime mucho, mucho mejor que el valor de píxel puro.



Entonces todo es exactamente igual que en JPEG. Transformará el bloque resultante. Pero la peculiaridad de todo tipo de códecs diferentes es que no puede usar DCT (transformada discreta de coseno), sino algo más. Qué usar depende del códec.



Por otra parte, las mismas placas, pero a diferencia de JPEG, puede usar más de una placa para todo su archivo, y puede usar varias placas diferentes para diferentes bloques. Imagina que tienes una persona, por ejemplo, contra el cielo. Quizás, dado que el cielo es azul, no necesita una calidad especial allí, puede usar una calidad para el cielo, una placa. Y para una persona que tiene cualquier textura, ropa, use una calidad diferente, y resulta genial y efectivo.



Lo más reciente es lo que JPEG no tiene, y lo que JPEG es muy, muy escaso. Este es el uso de filtros. Cuando todos cosechamos, obtenemos artefactos tan desagradables después de la compresión. Si alguna vez ha comprimido archivos JPEG a baja calidad, debería ver cómo los JPEG se desmoronan simplemente en terribles bloques de pesadilla. En general, para deshacerse de estos artefactos, los códecs de video usan algo especial. Aplican filtros y los bordes de estos bloques se suavizan. La tecnología de los antiguos, que nos permitía hacer lo mismo con JPEG, era tal. Toma su JPEG, lo comprime muy, muy duro, luego lo dobla así para que no se note nada. En general, esto es casi lo mismo, pero ya se ha hecho a nivel de códec. Excelente.



Naturalmente, cuando lo intentamos y todo estaba listo, ahora necesitamos comprimir los bloques recibidos sin pérdida. Nos apretamos, bien hecho. El algoritmo de compresión es similar a JPEG, pero aún diferente. Aquí debe entenderse que la compresión sin pérdidas está limitada por el límite natural. Realmente queremos acercarnos a él, y la mejor manera de acercarnos a él es si usamos un algoritmo llamado codificación aritmética. Y también hay todo tipo de variaciones. Esto nuevamente depende del codificador, pero supongamos que hay una compresión sin pérdidas y aprox.



Durante mucho tiempo he querido llamar a estos códecs abstractos en el vacío por sus nombres propios. Una pequeña excursión histórica. ¿Qué pasó en 20 años? Estoy hablando solo de esos códecs de video que al menos de alguna manera son compatibles en la web. H.264 es un códec que admite todo y a todos. Esta es la solución predeterminada para todo el video. Después de cierto tiempo, después de unos años, aparece el códec de video VP8.

Aquí comienzan las guerras salvajes, los holivars sobre el tema de cuáles de estos códecs son mejores. Busqué en Google durante mucho tiempo, no hay respuesta. Se han escrito grandes artículos científicos sobre esto, pero en promedio, si digo lo mismo ahora, un tomate volará hacia mí. Pero, bueno, son lo mismo. Promedio. Entonces, ¿por qué necesitamos un segundo?

El segundo es necesario porque es gratis. Si usa H.264, debe llevar dinero MPEG en algunas circunstancias. Para VP8 no necesitas llevar dinero. Es bueno. Entonces, fotograma clave VP8: esto es WebP. De hecho, ¿por qué deberíamos inventar un nuevo formato de imagen? Tomamos el fotograma clave, nos esforzamos tanto que lo exprimimos todo. Lo llamamos todo un nuevo formato de imágenes, ¡y listo!

¿Qué pasa después? Luego, después de varios años, dos códecs de video más interesantes, de MPEG y de Google, aparecen casi simultáneamente. De Google - VP9, ​​de MPEG - H.265. Junto a H.265 hay un nuevo estándar de imagen llamado HEIF. No es compatible con navegadores, ni uno en absoluto. Pero es compatible con sus dispositivos Apple. El estándar HEIF es increíblemente interesante, porque es solo una abstracción de esta idea. En un contenedor HEIF, puede introducir fotogramas clave desde casi cualquier códec. Es decir, VP8 no es un formato moderno. Pero HEIF es moderno.

¿Qué pasa después? Ahora en una organización muy grande, que incluye Mozilla y Google, se está recortando un códec de video llamado AV1. La organización se llama Alliance for Open Media. La calidad del video AV1 es muchas veces mayor que todo lo que era antes. Es libre, es libre de regalías, es muy genial. Tenemos un buen contenedor HEIF. Todo lo que nos queda es empujar el fotograma clave AV1 en él. Y ya está hecho. El nuevo formato para insertar el fotograma clave AV1 en un contenedor HEIF se llama AVIF. Esto es lo que nos espera en el futuro. Tal vez algún día lo usaremos de forma nativa.

Pero podemos usarlo ahora. Acabamos de poner un fotograma del video en la página y decimos: voila, tienes una foto.



¿Cómo se hace esto en webp? WebP es, como dije, un fotograma clave VP8 empaquetado en un contenedor llamado riff. Hay un encabezado en el contenedor de riff. Allí, no lo creas, está escrito que esto es WebP. ¿Quién dudaría de eso? PNG dice que es PNG WebP, y ahí está.

Pero WebP tiene una característica interesante: el fotograma clave VP8 puede estar dentro de él, y esto es lo que generalmente se llama WebP. Pero el fotograma clave VP8 puede no serlo. En general, WebP admite compresión sin pérdidas. WebP sin pérdida es un formato completamente diferente que no tiene nada que ver con VP8, compresión con pérdida, etc. Por lo tanto, cuando alguien le dice que WebP es más efectivo que otra cosa, la primera pregunta es qué WebP algo? Porque si hablamos de compresión sin pérdidas, entonces hay un pasillo natural al que podemos esforzarnos. Estas diferencias, "60% más efectivas que ...", son más probables no sin pérdidas, sino WebP con pérdidas.

Bien, suficiente teoría, harto de eso, veamos algo ya. Clickable




Comencemos con esto. Tomamos una foto tomada por una cámara profesional. Recorta una pieza de 1000 por 1000 píxeles de ella. Esto, por cierto, se ve muy bien en el proyector. Comenzamos a considerar pequeños detalles. Al mismo tiempo, comprimimos esta pieza para obtener exactamente 15 kilobytes. Clickable Vea lo que sucede. JPEG cayó en bloques de inmediato. De hecho, baja calidad, esperábamos esto. Así es como se ve WebP. También cayó en bloques, pero estos bloques no son tan claramente visibles. Cuando usa el codificador WebP y lo controla con sus manos, puede controlar la fuerza del filtro que se usa en WebP. Y si desenrosca este filtro con más fuerza, puede deshacerse de una gran cantidad de artefactos de bloque. Por lo tanto, puramente teóricamente, estos bloques también se pueden eliminar.








Y aquí está AV1. Solo admiremos en silencio. Mira lo genial que es. AV1 es compatible con Firefox, en Chrome, por lo que puede usar el video AV1 en lugar de una imagen si de repente lo desea. Clickable Hay un spoiler, en vano lo agregué. La situación cuando PNG derrota a WebP. Sí, PNG en este caso es más efectivo que WebP. Esto se debe a que usé WebP con pérdida. Clickable ¿Qué hice con el peengeshka? Hice el modo de color indexado, es decir, corté la paleta, en mi opinión, a 16 colores. Es bastante efectivo para una imagen en blanco y negro. Resultó bien, se contrajo mucho. Para WebP con pérdida de calidad, tenemos un tamaño más grande. Sin embargo, para sin pérdidas, esto se espera, es más eficiente que peengeshka. Tenemos una victoria











Resumo Las punzadas empotradas muy geniales pueden vencer los formatos de compresión con pérdida y no derrotar a WebP sin pérdida. Tristemente, tristemente. Clickable Quizás te atormente la pregunta: ¿por qué haces esto? ¿Sabemos qué es SVG? Y lo sé, pero para algunos tamaños, PNG es más eficiente. Esta imagen resulta ser más efectiva que SVG para tamaños como 200 por 200. Luego, SVG, por supuesto, gana. Clickable Ahora echemos un vistazo a Mike. Éste es Mike. Sus dimensiones son de 3000 por 3000 píxeles. JPEG vs WebP. Era obvio aquí que JPEG estaba ganando. Pero en este caso, obtuve aproximadamente un seis por ciento de victoria por aproximadamente la misma calidad visual. Esta es una característica de la foto y cómo preparé esta foto. Entonces puedes preguntarme cómo lo hice.












Se puede hacer clic.

Aún así, todo depende en gran medida de los parámetros del codificador. Si se esfuerza mucho y desenrosca los parámetros del codificador de una manera especial, JPEG comenzará a derrotar a WebP en tamaño para la misma calidad visual. Me gustaría concluir que los gatos se encogen mejor que JPEG, pero no. Este es solo un ejemplo de cómo puede desenroscarlo de la manera que desee si lo desea. Clickable Esto es de muy baja calidad. JPEG está cayendo en bloques. Esto es especialmente evidente en el proyector: la nariz se volvió azul al perro, se volvió cuadrada. WebP no está tan enfermo. Todo parece ser genial y bueno, pero la cuestión es que, para cualidades muy, muy bajas, WebP proporciona aproximadamente dos, o quizás tres veces el tamaño del archivo que JPEG. Así que aquí también debes pensar qué calidad quieres. Clickable









Esta es la comparación más honesta. Entonces tienes que comparar, porque H.264 y WebP son similares. ¿Quién crees que ganó aquí? H.264. Pero para ser sincero, el experimento no fue del todo limpio. En el buen sentido, tanto en WebP como en H.264, el cuadro de video es aproximadamente inequívoco. Se puede hacer clic Pero con AV1, todo está absolutamente claro. Treinta por ciento gana con la misma calidad visual. ¡Hurra! Se puede hacer clic en Es muy importante comprender qué tipo de imagen coloca y cómo responde este o aquel formato a la calidad de la imagen. Aquí el perro en formato WebP pesa 79 kilobytes en calidad como aproximadamente el 75% frente a 56 kilobytes en JPEG. ¿Por qué está pasando esto?











Debido a que no hay un solo códec de video, ni un solo formato puede comprimir correctamente el ruido. Si su imagen tiene muchas distorsiones tan agudas, puntos y algo más, lo más probable es que tenga problemas con la compresión. Si puede tomar alguna otra foto y eliminar este ruido, elimínelo.

Entonces, las imágenes son algo complicado. ¿Pueden ralentizar su interfaz? Una pregunta importante y buena.



Respuesta: muy probablemente no. ¿Por qué sucede? Porque cuando la imagen se decodifica, sucede en una secuencia separada. Pero hay una excepción: si dibuja algo en el lienzo, debe recordar que la decodificación de la imagen se producirá en la transmisión principal y que los botones no se pueden presionar en ese momento.



Si realmente quiere hacer un trato, abra Chrome, busque los hilos rasterizados correspondientes y el evento Image Decode, lo encontrará.



Si tiene mucha, mucha curiosidad, puede ir a la pestaña de seguimiento y ver allí con detalles lo que sucede al decodificar una imagen.

Herramientas de optimización


Lo más importante son las herramientas de optimización. Ahora sabemos más o menos lo que queremos. Queda por entender cómo hacemos esto.



La herramienta de optimización de imagen más importante es el diseñador, no importa cuán extraño suene. Solo esta persona maravillosa sabe qué problema quieres resolver con él. No agregamos imágenes a las páginas para optimizarlas, sino para impresionar a los usuarios. Para mantener un equilibrio entre el grado de optimización y la experiencia del usuario, use un diseñador que ayude mucho.


Enlace de la diapositiva La

segunda herramienta es nuestro código abierto marciano, del que prometí hablar. Esta cosa se llama imgproxy y resuelve todos nuestros problemas en general. En mis proyectos solo uso imgproxy, esta cosa puede hacer casi todo lo que quiero.



¿Cómo funciona? ¿Tienes algún deseo para la foto? Desea una imagen de cierto tamaño con una cierta optimización. Y en algún lugar lejano tiene una imagen de cualquier resolución, tal vez en la computadora local, o tal vez en algún lugar del usuario o en general en cualquier lugar. Solo necesita crear una url especial y pedirle a imgproxy que cambie el tamaño de su imagen. Este es un servicio de este tipo, puede estar en la nube o en otro lugar. Es decir, tenías un gato enorme, envías una URL especial a imgproxy. Él hace todo lo que quieras sobre la marcha.



Si eso no suena claro, veamos cómo se ve la solicitud de imgproxy. Primero, necesita decir dónde se encuentra imgproxy. En segundo lugar, si no desea ser absorbido agresivamente, entonces la URL que está solicitando sería buena para firmar digitalmente. No puede hacer esto, esto es solo una medida adicional de protección.

Además, si desea cambiar el tamaño, directamente en la url pase los parámetros de cambio de tamaño. Si desea optimizar, lo mismo. Solo necesita transferir la dirección original de su imagen.



Si desea optimizaciones manuales, hay un gran conjunto de herramientas. No los describiré a todos ahora. Los materiales para el informe, que le enviaré, lo tienen todo.



Aquí está lo más genial y útil. Estas todas las imágenes no son tan complicadas. Creo que logré transmitirte esto. Si está interesado, tome su lenguaje de programación favorito, probablemente JavaScript, aunque lejos de ser un hecho, y comience a resolverlo.

Si desea hacer esto en un navegador, por favor. Probablemente necesite un enlace que probablemente esté escrito en más o en C. Pero, ¿qué le impide compilar todo esto en WebAssembly? Hay una aplicación genial llamada Squoosh. Hace exactamente eso. Usted también puede, intente, será genial. De verdad me gusta.

Gracias a todos por su atención. Materiales para el informe - por referencia .

All Articles