Imagens como caixas - o que há dentro? Relatório em Yandex

Fotos e vídeos são "caixas pretas", nas quais há muitas coisas interessantes e incompreensíveis. Mas você pode olhar dentro de alguns formatos, mudar tudo lá e ver o que acontece.

Polina Gurtovaya, da empresa Evil Marcianos, falou em nossa conferência  Frontend , em fevereiro. Com a ajuda do experimento, Polina descobriu como transformar imagens simples em "imagens efetivas" com métricas. As ferramentas que podem fazer isso por nós, Polina examinou mais perto do final do relatório. O resultado foi uma grande excursão ao interior e aos princípios de operação de vários formatos: de PNG e JPEG a AV1 e exóticos.


- Olá a todos. Meu nome é Polina, sou a frente da empresa "Evil Marcianos".

Talvez você conheça marcianos de nossas muitas fontes abertas. Eu vou falar um pouco sobre ele mais tarde. E provavelmente devo dizer que ainda estamos desenvolvendo produtos, e não apenas vendo código aberto.



Os materiais para o relatório estarão disponíveis para você através de um link maravilhoso no repositório no GitHub.



Vamos falar um pouco sobre otimização. Quando lidamos com eles, o problema é que eles funcionam bem se entendermos o que estamos fazendo. Se não entendermos, isso acaba mal. Infelizmente, quando se trata de otimização de imagens, tudo aqui não é muito legal. Podemos não otimizar as imagens e, em seguida, haverá monstros de dois metros no produto, é tudo triste e triste.

Se otimizarmos, o que estamos fazendo? Pensamos: aqui temos uma foto, isso é algum tipo de caixa preta misteriosa, e o programa otimizador faz algo com essa foto, algum tipo de xamanismo preto. A qualidade da otimização que obtemos é um pouco duvidosa.



Vejamos um exemplo. Eu tenho um gato no formato PNG. Eu acho que precisamos otimizá-lo. O que eu estou fazendo? Crio uma versão WebP e cuidadosamente coloco as duas imagens em uma tag <picture>. Você acha que estou bem aqui ou não? Por que há tão poucas mãos? Estou muito bem feito!

Fiz tudo certo, mas a versão WebP ficou dois kilobytes a mais que a original. Isso não é o que eu queria.




Outra otimização, tentativa número 2. Eu tenho um pequeno recipiente na página e um gato grande e grande. Eu quero colocar um gato grande em um pequeno recipiente. O que eu estou fazendo? Estou redimensionando porque é estúpido direcionar bytes pela rede se o tamanho do meu contêiner for pequeno. Obviamente, levo em consideração a proporção de pixels do dispositivo. Você acha que estou indo bem aqui ou não? Terminei! E olha o que eu fiz.

Estou usando a biblioteca libvips. Ela é muito legal e popular, e do meu enorme e feliz gato leve, eu tenho um gato pequeno e muito pesado. O selo aumentou 2,5 vezes (em bytes) durante o redimensionamento (em pixels). Legal, sim?



Em geral, para que isso não aconteça conosco, entendamos como otimizar nossas imagens para nossa tarefa e, em geral, para que pelo menos entendamos o que está acontecendo, vamos olhar para a caixa e entender o que está dentro.



Vamos começar olhando para um formato tão interessante como PNG. Em torno de cada site, um pequeno peengshechka está escondido em algum lugar. Desta vez. Portanto, eles devem ser entendidos. Segundo: PNG - formato de compactação sem perdas. Isso significa que garantimos uma combinação perfeita com o original em pixels, mas, ao mesmo tempo, somos limitados por natureza, não podemos comprimir menos do que quanto.



Peengeshka se dobra em um recipiente, como qualquer formato de imagem. Uma das primeiras coisas que precisamos dizer ao programa se ele lê tudo é o que está dentro. Se você assumir que seus decodificadores determinam imagens por extensão, isso não é verdade.

Pengashka relata que é PNG, os primeiros oito bytes em seu contêiner. Diz "PNG". Além disso - novamente, isso é característico de qualquer contêiner - você tem um layout de pedaços. Ou seja, as informações são agrupadas em pedaços, elas são de alguma forma organizadas. Como - define o contêiner. Em PNG, fica assim: você tem quatro bytes responsáveis ​​pelo comprimento e quatro bytes responsáveis ​​pelo tipo de pedaço. Que tipos - falaremos um pouco mais tarde. 

Se o pedaço tiver um comprimento diferente de zero, ele terá uma carga útil. Além disso, existe uma soma de verificação. Você está verificando se alguma coisa foi batida lá. Em seguida, vêm os seguintes blocos.



Analisar não apenas um arquivo PNG, mas quase qualquer um é bastante fácil. Veja o FileReader, esta é uma API do navegador. Lemos o arquivo usando o FileReader. Assim que lemos, cortamos esse arquivo em pedaços. Não fornecerei aqui o código da função split to chunks, mas você pode adivinhar que existe uma combinação complexa de if e for. 




Ok, nós cortamos, vamos ver o que acontece. Temos vários tipos de pedaços, e eles são muito, muito característicos de quase qualquer formato. O primeiro é chamado IHDR. Há vários pedaços chamados IDATs. Esses nomes podem parecer um pouco estranhos para você, mas agora vamos descobrir o que é. Quando tudo termina, vemos o pedaço final.



Vamos dar uma olhada mais de perto nos pedaços. O IHDR é um meta-pedaço, e quase todas as figuras têm esse meta-pedaço. É chamado de forma diferente, é organizado de forma diferente, mas é mais provável. Sem ele, seu descompressor - algo que mostra peengeshki ou não peengeshki - não pode mostrar nada. O que há nesse pedaço? Novamente, o conteúdo é típico para a maioria dos formatos. Esta é a altura e a largura. A altura e a largura são costuradas no seu arquivo, trata-se de você. Em seguida, aparecem os sinalizadores de panache típicos: bitDepth, colorType e entrelaçamento. 



Antes de falarmos sobre o que essas bandeiras significam e por que são muito, muito importantes para nós, vamos ver como armazenamos pixels em pangshes. Nas peaneshs, os pixels são armazenados dentro de um pedaço chamado IDAT. Em um bom cenário, os pixels são um certo número de números compactados em um pedaço, e esse pedaço é compactado pelo algoritmo de compactação Deflate. Quem usou o algoritmo de compactação Deflate? Ok, quando foi a última vez que você compactou alguma coisa? Você sabia que Deflate é gzip? Então eu acho - muitos o usaram.

Mas no peengeshah, outra coisa interessante aparece, usada em um grande número de formatos, mas provavelmente em todos. Esse dispositivo é chamado de codificação preditiva. O fato é que nossas imagens não são pixels aleatórios. O que é pintado em nossa pequena imagem está de alguma forma conectado. Existem algumas áreas escuras, áreas claras e assim por diante.

Estamos tentando explorar esse fato e, em vez de armazenar o valor de pixel nessas células azuis, estamos tentando prever esses pixels com base nos anteriores. Em PNG, essas previsões são muito simples e são empacotadas no primeiro byte antes da linha com pixels. Uma previsão pode ser assim, por exemplo, não vamos prever nada e apenas colocar tudo como está. Ou, por exemplo, podemos dizer o seguinte: mas vamos manter apenas a diferença entre o pixel atual e o pixel anterior.

Se você tiver a mesma cor na sua linha, todos os zeros terão tudo, tudo será perfeitamente comprimido, isso é muito legal.



Mas agora vamos falar sobre o que um pixel realmente significa. Um pixel aparece em uma peengesh como um número de números. Ao manipular quantos números existem, você pode compactar com muita força o PNG - três vezes.

Que opções existem? O primeiro é True Color e alfa. Temos três canais, três cores, três números por cor. Além de um canal responsável pela transparência.

O tamanho desse numeral em bits é bitDepth, a mesma flag que vimos no bloco IHDR. Quanto menor o seu bitDepth, menor o arquivo, mas menos cores você pode apresentar a eles. Um número típico é 8. Quanto custa? Na minha opinião, haverá 16 milhões com alguma coisa.

Ok, a primeira otimização que você pode fazer é jogar fora os canais alfa na sua peengesh. Este será um colorType diferente.

Você pode otimizar ainda melhor e usar apenas um em vez de quatro números. Mas o problema é que, então, seu peengeshka deve ser preto e branco.

Se você ainda deseja apenas um número e deixa as cores, isso também pode ser feito. O que está acontecendo aqui? Você pega todas as cores dentro do seu peengeshka e as corta em um pedaço separado. Chame de paleta. Ainda dentro da amostra, responsável pelo pixel dentro do pedaço IDAT, você apenas armazena o índice dessa paleta. Se você tiver uma captura de tela sem um plano de fundo intrincado ou algum desenho, essa coisa será perfeita. Ela aperta peengeshki certo uau!

Outra coisa importante a dizer é o entrelaçamento. O que é entrelaçamento? É quando você envia seu peengeshka gradualmente. Você não tem um peengeshka, mas várias imagens. Cada imagem é chamada de digitalização.



Ao mesmo tempo, dentro da paengashka, você classifica os pixels de maneira que alguns pixels sejam arrancados das fotos, uma imagem vem de lugares especiais. A próxima parte é outra e assim por diante. Uma técnica aparentemente interessante como o JPEG progressivo.

Mas parece assim. Não tenho certeza se você deseja que seus usuários vejam isso, embora possa ser útil para sua tarefa.

O segundo e muito sério problema do PNG entrelaçado é que, assim que você entrelaça seu peengeshka, o tamanho do seu peengeshka se torna maior. E não mais tão fraco, em alguns kilobytes sua peengeshka de seis kilobytes crescerá se você desligar o Entrelaçado. Portanto, pense com cuidado, quer você queira ou não.



Falamos apenas sobre PNG, mas com isso você pode tirar conclusões importantes e úteis. Primeira conclusão: o tamanho do seu arquivo, você não acredita, depende do que é desenhado lá. O quadrado preto encolhe melhor do que o gato, não darei nenhuma recomendação aqui. Segundo, mais importante: o tamanho do seu arquivo depende muito do codificador e dos parâmetros que você transfere.

Se você quiser ver como os codificadores horríveis funcionam, use os do navegador. Como isso é feito? Pegue o arquivo PNG, desenhe-o na tela, clique em Salvar como e compare o que aconteceu com o que aconteceu. Em geral, o Chrome aumentará o tamanho do arquivo em 2,5 vezes, o Firefox - em 1,6.

A propósito, também depende sempre do formato, ou seja, não apenas PNG deve ser usado. Vamos entender por que tudo depende do formato e de quais opções interessantes ainda temos.



Para fazer isso, falaremos sobre a tecnologia dos antigos, sobre JPEG. Obviamente, você não pode subestimar a importância do JPEG. Eles são encontrados em toda parte. Eles são tão legais, bons e, mais ainda, selos em JPEGs são uma história bastante comum. Mas o JPEG é uma coisa bastante complicada, e é complicada devido ao fato de que o JPEG é uma compactação com perdas. Além disso, o JPEG é sempre uma compactação com perdas. A qualidade JPEG 100% ainda comprime com a perda.

Como obtemos compactação com perdas? Muito simples. Pegamos alguma fonte, jogamos fora os dados e depois compactamos sem perda. Ou seja, mais um passo.



Vejamos como fazemos perdas em nossos JPEGs. Então, você tem um gato com um tamanho de 32 por 32. Para darmos o primeiro passo com as perdas, precisamos mudar nossos canais. Geralmente falamos de imagens em termos de RGB. Mas percebemos as cores um pouco complexas. Nosso cérebro geralmente é um grande problema, embora nos ajude muito a comprimir JPEG.

Percebemos muito bem o preto e o branco. Mesmo se você olhar atentamente, notará que os detalhes na imagem em preto e branco distinguem melhor. Acabamos de colocar essa imagem em preto e branco em um canal separado. É chamado Y. Na verdade, a barra Y. Não estamos fazendo nada com ele, apenas o deixamos como está.

Existem mais dois canais responsáveis ​​pela cor. Estes são CB e CR. Com esses canais já podemos nos divertir um pouco. Aqui com esses canais, produzimos um procedimento interessante chamado Downsampling. Tomamos e reduzimos a resolução deste canal. Para JPEG, é típico reduzir pela metade. Ou seja, você obtém três fotos - uma original e duas pela metade. Viva!

O que faremos a seguir? Nós não compactamos JPEG, não como um arquivo inteiro. Nós o dividimos em blocos e comprimimos ainda mais, já estamos começando blocos. Os blocos em JPEG têm tamanho de 8 por 8 e veja o que acontece com eles. Vamos ver o canal Y. CB e CR são todos iguais.



Portanto, um bloco não é uma imagem, mas números. Precisamos fazer perdas em JPEG. Esse bloco é 8 por 8, 64 pixels, qual jogar? O da esquerda, o da direita, o do meio? Não está claro. Mas há uma matemática legal que nos permite resolver esse problema.

Essa matemática é chamada - agora, por favor, não fique nervosa se alguém se lembrar do terrível passado institucional - a discreta transformação do cosseno. Portanto, com a ajuda dessa transformação discreta de cosseno, você pode converter esses números em seu bloco para que sejam importantes e sem importância entre eles.

Importante: após a conversão, números importantes permanecem na parte superior esquerda do bloco. No canto inferior direito permanecem números sem importância.

Em seguida, você precisa fazer a sua perda de JPEG. Isso também é muito fácil de fazer. Esse truque é chamado quantização. Desculpe se você quer dormir agora, mas isso é importante, acredite. Portanto, essa quantização funciona de maneira bastante simples. Você pega seu bloco e um prato especialmente projetado. Esta placa é determinada pelo seu programa de codificador. Os números que apareceram no seu bloco, você divide por este termo da placa por número e número inteiro. O que você obtém como resultado?

Como os números são grandes na parte inferior direita da placa, haverá apenas zeros.



E, ao mesmo tempo, seu JPEG, seu bloco será compactado perfeitamente. Você terá um pequeno número de números que desviará em um zig-zag tão intrincado, que os zeros desaparecerão e, gritos, nosso bloco está pronto para compactação. Depois, precisamos compactá-lo com um algoritmo de compactação sem perdas. O JPEG usa a Huffman Coding, seja ela qual for.



Como é embalado em um recipiente? Recipientes JPEG parecem um pouco idiotas, eu tenho medo deles. Porque você vê os dois primeiros bytes e diz que provavelmente é JPEG. Mas até agora não está claro.

Em seguida, você precisa procurar por dois meta chunks. Por que dois? Porque o JPEG é um conjunto muito grande de padrões diferentes. O que chamamos de JPEG é, por padrão, chamado JIFF. Esta é uma extensão especial do padrão JPEG. Não vou continuar - em geral, existem dois meta chunks, apenas confie em mim. Esses meta-chunks contêm informações sobre a largura e a altura do seu arquivo e a versão do JPEG. Imagine, o JPEG tem mais versões! Além disso, é JPEG progressivo? Esta é uma bandeira importante. Ele fala sobre como seus blocos serão distribuídos ainda mais.

Se o JPEG não for progressivo, o que você precisa para decodificar seus blocos? Qualidade JPEG, este mesmo prato. A placa na qual você divide seus blocos é de qualidade. Mas o JPEG tem duas qualidades. A primeira qualidade é responsável pelo canal Y, a segunda - pelos canais CB e CR, é isso que determina a cor. Como colocamos a qualidade em um arquivo e compactamos tudo com um algoritmo de compactação sem perdas, ainda precisamos de um dicionário especial do Huffman Tables para expandir isso.

Em seguida, vem seus blocos e seu JPEG acaba.



Ok, uma história progressiva. Tudo é exatamente o mesmo. No começo, você tem um meta-pedaço. Em seguida, vem a sua qualidade na forma de 64 números, mais 64 números. E então apenas os mesmos blocos, mas um pouco diferente com os números distribuídos. Primeira parte dos blocos, depois outra parte, outra parte e assim por diante. À medida que você recebe esses blocos, o navegador faz uma aproximação do seu JPEG, porque, de fato, esses números são uma aproximação do seu arquivo.



Sobre o JPEG que terminamos, você pode expirar, está tudo bem. Vamos falar de algo interessante como o JPEG 2000. Algum de vocês em produção usa o JPEG 2000? Ok, quem já ouviu falar disso? E qual de vocês leu no Lighthouse - “usa formatos modernos”?

Em geral, o JPEG 2000 é um formato interessante interessante, que primeiro é mais eficaz que o JPEG. Em segundo lugar, você não vai acreditar, em alguns casos é mais eficaz que o WebP, sobre o qual falaremos mais adiante.

Ele sabe ser transparente, sabe como comprimir sem perdas. Apenas o formato perfeito. Mas, infelizmente, sim, ele só funciona no Safari.

Vale ressaltar que o JPEG 2000 é projetado de uma maneira muito complexa e funciona em matemática interessante chamada transformação de wavelet. Se você está subitamente interessado, pesquise no Google e iremos mais longe.



De repente, precisamos conversar sobre o vídeo. Todo este relatório é sobre otimização de imagens e imagens. Mas o vídeo aqui é muito importante, você verá o porquê agora. Quando pensamos em um vídeo, a primeira palavra que vem à nossa mente é "codec". O vídeo precisa ser codificado de alguma forma e, para mostrar o vídeo, precisamos decodificá-lo. Se decodificarmos o fluxo de vídeo, o que obteremos?

Primeiro de tudo, temos um conjunto de quadros. Mas não pense nesses quadros como imagens no GIF. Tudo errado. Quais quadros são muito dependentes do codec. Mas, no caso geral, você pode assumir que possui um quadro-chave. Você pode tirar um gato do quadro-chave - no sentido, qualquer imagem que esteja nesse quadro-chave. E existem quadros dependentes. É impossível tirar um gato do quadro dependente, porque o quadro dependente armazena não apenas informações não sobre a imagem, se houver, mas também sobre como os blocos do quadro anterior ou anterior se moveram sobre isso. Portanto, você não pode obter uma imagem para um quadro dependente até decodificar um pouco.

Agora, falaremos apenas sobre o quadro-chave e a compressão intra-quadro. É assim que você comprime uma imagem dentro de um quadro-chave.

Vamos examinar um codec abstrato no vácuo e compará-lo com o JPEG. Até agora parece - por que fazer isso? Tudo ficará mais claro, confie em mim.



Mais uma vez repetimos a mesma coisa que fazemos com JPEG,. Você tira uma foto, a divide em canais, reduz a amostragem para os canais. A mesma história aqui. Então você divide esta imagem em blocos. Mas já existem recursos. Primeiro de tudo, o tamanho do bloco em que você está invadindo depende do seu codec. E esses blocos podem ser muito grandes. Para JPEG - 8 por 8. Para codecs de vídeo - pode ser, por exemplo, 128 por 128.

Mais. Se você receber alguns detalhes muito pequenos na sua imagem, você ainda pode subdividir os blocos um pouco, aproximadamente para o tamanho 4 por 4. Como você quebra os blocos, esse algoritmo de particionamento depende do codec.

E o mais recente - o tamanho máximo do bloco, novamente, é específico para o seu codec. Um codificador faz parte do codec, para ser entendido na terminologia. Aqui ainda somos semelhantes ao JPEG.



O que não parece JPEG é codificação preditiva. Nós conversamos sobre ele em parte sobre peengeshki. A compactação de vídeo intraframe é tão legal e eficaz por causa disso. O que está acontecendo aqui?

Estamos tentando prever os pixels de cada bloco com base nos anteriores. Ou seja, não armazenamos pixels na forma bruta, os prevemos. As opções de previsão são muitas. Dentro de um codec, podemos usar diferentes variantes de previsões. Além disso, para todos os tipos de codecs intrincados dessas opções, até 35, por exemplo. Como você pode fazer isso. Vamos ver um exemplo.

Aqui você tem o bloco. Você diz: eu quero prever pixels lá. Você olha para a esquerda, olha para cima e lembra o que resta e acima. Em seguida, você pega todos os valores de pixel encontrados, calcula a média e preenche-os com um bloco e diz: Eu previ. Se você adivinhou certo, e a propósito, na pequena foto onde existem setas azuis, adivinhou certo, então você é ótimo, não precisa fazer mais nada. Mas, se você ainda não adivinhou, precisará salvar a diferença entre o que é realmente e o que previu. Essa diferença comprime muito, muito melhor que o valor puro do pixel.



Então tudo é exatamente igual ao JPEG. Você transformará o bloco resultante. Mas a peculiaridade de todos os tipos de codecs diferentes é que você pode usar não o DCT (transformação discreta de cosseno), mas outra coisa. O que usar depende do codec.



Em seguida, novamente as mesmas placas, mas, diferentemente do JPEG, você pode usar mais de uma placa para todo o arquivo e várias placas para blocos diferentes. Imagine - você tem uma pessoa, por exemplo, contra o céu. Talvez, como o céu é azul, você não precise de uma qualidade especial lá, você pode usar uma qualidade para o céu, um prato. E para uma pessoa que tem alguma textura, roupas, use uma qualidade diferente, e ela se torna legal e eficaz.



O mais recente é o que o JPEG não possui e o que o JPEG está faltando. Este é o uso de filtros. Quando todos nós colhemos, temos esses artefatos desagradáveis ​​após a compactação. Se você já compactou JPEGs para baixa qualidade, deve ver como os JPEGs se desfazem simplesmente em terríveis blocos de pesadelo. Em geral, para se livrar desses artefatos, os codecs de vídeo usam algo especial. Eles aplicam filtros e as bordas desses blocos suavizam. A tecnologia dos antigos, que nos permitia fazer o mesmo com o JPEG, era essa. Você pega seu JPEG, comprime-o com muita força e depois dobra-o assim para que nada seja perceptível. Em geral, isso é praticamente o mesmo, mas já foi feito no nível do codec. Ótimo.



Naturalmente, quando tentamos e tudo foi feito, agora precisamos compactar os blocos recebidos sem perda. Apertamos, bem feito. O algoritmo de compactação é semelhante ao JPEG, mas ainda diferente. Aqui deve ser entendido que a compressão sem perdas é limitada pelo limite natural. Nós realmente queremos nos aproximar dela, e a melhor maneira de nos aproximarmos dela é se usarmos um algoritmo chamado codificação aritmética. E também existem todos os tipos de variações. Isso depende novamente do codificador, mas vamos supor que haja compressão sem perdas e aprox.



Há muito tempo eu queria chamar esses codecs abstratos no vácuo por seus nomes próprios. Uma pequena excursão histórica. O que aconteceu em 20 anos? Estou falando apenas sobre os codecs de vídeo que são pelo menos de alguma forma suportados na web. O H.264 é um codec que suporta tudo e todos. Esta é a solução padrão para o vídeo inteiro. Após um certo período de tempo, após alguns anos, o codec de vídeo VP8 aparece.

Aqui começam as guerras selvagens, holivares sobre o tópico sobre quais desses codecs são melhores. Pesquisei no Google por muito tempo - não há resposta. Grandes artigos científicos foram escritos sobre isso, mas, em média, se eu disser o mesmo agora, um tomate voará para mim. Mas tudo bem, eles são iguais. Média. Então, por que precisamos de um segundo?

O segundo é necessário porque é gratuito. Se você usa o H.264, é necessário transportar dinheiro MPEG em algumas circunstâncias. Para o VP8, você não precisa carregar dinheiro. É bom. Então, quadro-chave VP8 - este é WebP. De fato, por que devemos inventar um novo formato de imagem? Pegamos o quadro-chave, tentamos tanto, esprememos tudo. Chamamos tudo isso de um novo formato de fotos, e pronto!

O que acontece depois? Depois de vários anos, mais dois codecs de vídeo interessantes, do MPEG e do Google, aparecem quase simultaneamente. Do Google - VP9, ​​do MPEG - H.265. Ao lado de H.265, há um novo padrão de imagem chamado HEIF. Não é suportado por navegadores, nem um. Mas é suportado pelos seus dispositivos Apple. O padrão HEIF é incrivelmente interessante, porque é apenas uma abstração dessa idéia. Em um contêiner HEIF, você pode compactar o quadro-chave de praticamente qualquer codec. Ou seja, o VP8 não é um formato moderno. Mas o HEIF é moderno.

O que acontece depois? Agora, em uma organização muito grande, que inclui Mozilla e Google, um codec de vídeo chamado AV1 está sendo visto. A organização é chamada Alliance for Open Media. A qualidade do vídeo AV1 é muitas vezes superior a tudo o que era antes. Ele é livre, ele é livre de royalties, ele é muito legal. Temos um contêiner HEIF tão bom. Tudo o que resta para nós é colocar o quadro-chave AV1 nele. E está feito. O novo formato para enviar o quadro-chave AV1 para um contêiner HEIF é chamado AVIF. É isso que nos espera no futuro. Talvez um dia a usaremos nativamente.

Mas podemos usá-lo agora. Colocamos apenas um quadro do vídeo na página e dizemos: voila, você tem uma foto.



Como isso é feito no webp? WebP é, como eu disse, um quadro-chave VP8 empacotado em um contêiner chamado riff. Existe esse cabeçalho no contêiner de riff. Lá, não acredite, está escrito que este é WebP. Quem duvidaria disso. PNG diz que é PNG WebP, e aí está.

Mas o WebP tem um recurso interessante: o quadro-chave VP8 pode estar dentro dele, e isso é o que geralmente é chamado de WebP. Mas o quadro-chave VP8 pode não ser. Em geral, o WebP suporta compactação sem perdas. O WebP lossless é um formato completamente diferente que nada tem a ver com o VP8, a compactação com perdas, etc. Portanto, quando alguém lhe diz que o WebP é mais eficaz do que qualquer outra coisa, a primeira pergunta a ser feita é: WebP alguma coisa? Porque se falamos de compressão sem perdas, existe um corredor natural pelo qual podemos nos esforçar. Essas diferenças, "60% mais eficazes que ...", provavelmente não são sem perdas, mas WebP com perdas.

Certo, teoria suficiente, farto disso, vejamos algo já. Clicável




Vamos começar com isso. Tiramos uma foto tirada por uma câmera profissional. Recorte um pedaço de 1000 por 1000 pixels. Aliás, parece muito legal no projetor. Começamos a considerar pequenos detalhes. Ao mesmo tempo, compactamos esta peça para obter exatamente 15 kilobytes. Clicável Veja o que acontece. O JPEG caiu em blocos imediatamente. De fato, baixa qualidade, esperávamos isso. É assim que o WebP se parece. Também caiu em blocos, mas esses blocos não são tão claramente visíveis. Ao usar o codificador WebP e controlá-lo com as mãos, você pode controlar a força do filtro usado no WebP. E se você desapertar esse filtro com mais força, poderá se livrar de um grande número de artefatos de bloco. Portanto, puramente teoricamente, esses blocos também podem ser removidos.








E aqui está o AV1. Vamos apenas admirar silenciosamente. Olha como ele é legal. O AV1 é suportado no Firefox, no Chrome, para que você possa usar o vídeo AV1 em vez de uma imagem, se desejar repentinamente. Clicável Há um spoiler, em vão eu o adicionei. A situação em que o PNG derrota o WebP. Sim, PNG neste caso é mais eficaz que WebP. Isso ocorre porque eu usei WebP com perdas. Clicável O que eu fiz com o peengeshka? Eu fiz o modo de cores indexadas, ou seja, cortei a paleta, na minha opinião, em 16 cores. É bastante eficaz para uma imagem em preto e branco. Acabou bem, contratou muito. Para WebP com perda de qualidade, temos um tamanho maior. No entanto, para perdas, isto é esperado, é mais eficiente que peengeshka. Temos uma vitória.











Eu resumo. Pangshes embutidos muito legais podem derrotar formatos de compactação com perdas e não derrotar WebP sem perdas. Infelizmente, infelizmente. Clicável Talvez você esteja atormentado com a pergunta: por que você está fazendo isso, sabemos o que é SVG? E eu sei, mas para alguns tamanhos, PNG é mais eficiente. Essa imagem acaba sendo mais eficaz que o SVG para tamanhos de 200 a 200. Então o SVG, é claro, vence. Clicável Agora, vamos olhar para Mike. Este é o Mike. Suas dimensões são 3000 x 3000 pixels. JPEG vs WebP. Era óbvio aqui que o JPEG estava ganhando. Mas, neste caso, obtive cerca de seis por cento de vitória pela mesma qualidade visual. Esta é uma característica da foto e como eu a preparei. Você pode então me perguntar como eu fiz isso.












Clicável

, mas tudo depende muito dos parâmetros do codificador. Se você se esforçar muito e desaparafusar os parâmetros do codificador de uma maneira especial, o JPEG começará a diminuir o tamanho do WebP para a mesma qualidade visual. Gostaria de concluir que os gatos encolhem melhor que o JPEG, mas não. Este é apenas um exemplo de como você pode desaparafusá-lo da maneira que desejar, se desejar. Clicável Esta é uma qualidade muito baixa. JPEG está caindo em blocos. Isso é especialmente evidente no projetor - o nariz ficou azul para o cachorro e ficou quadrado. WebP não está tão doente. Tudo parece legal e bom, mas o fato é que, para qualidades muito, muito baixas, o WebP oferece cerca de duas ou talvez três vezes o tamanho do arquivo que o JPEG. Então aqui você também precisa pensar em qual qualidade deseja. Clicável









Essa é a comparação mais honesta. Então você tem que comparar, porque H.264 e WebP são semelhantes. Quem você acha que ganhou aqui? H.264. Mas, para ser sincero, o experimento não foi totalmente limpo. De uma maneira boa, tanto no WebP quanto no H.264, o quadro de vídeo é aproximadamente inequívoco. Clicável Mas com o AV1, tudo é absolutamente claro. Trinta por cento ganham na mesma qualidade visual. Viva! Clicável É muito importante entender que tipo de imagem você coloca e como esse ou aquele formato responde à qualidade da imagem. Aqui, o cão no formato WebP pesa 79 kilobytes em qualidade, cerca de 75%, contra 56 kilobytes em JPEG. Por que isso está acontecendo?











Como nem um único codec de vídeo, nem um único formato pode compactar adequadamente o ruído. Se a sua imagem apresentar muitas distorções, pontos e outras coisas nítidas, é provável que você tenha problemas com a compressão. Se você puder tirar outra foto e remover esse ruído, remova-o.

Então, as imagens são uma coisa complicada. Eles podem diminuir a velocidade da sua interface? Uma pergunta importante e boa.



Resposta: provavelmente não. Por que isso acontece? Porque quando a imagem é decodificada, acontece em um fluxo separado. Mas há uma exceção: se você desenhar algo na tela, lembre-se de que a decodificação da imagem ocorrerá no fluxo principal e os botões poderão não ser pressionados nesse momento.



Se você realmente deseja fazer um acordo, abra o Chrome, procure os threads de rasterização correspondentes e o evento Image Decode, você o encontrará.



Se você estiver muito, muito curioso, poderá ir para a guia Rastreio e ver com detalhes o que acontece ao decodificar uma imagem.

Ferramentas de otimização


O mais importante são as ferramentas de otimização. Agora sabemos aproximadamente o que queremos. Resta entender como fazemos isso.



A ferramenta de otimização de imagem mais importante é o designer, por mais estranho que pareça. Somente essa pessoa maravilhosa sabe qual problema você deseja resolver com ela. Não adicionamos imagens às páginas para otimizá-las, mas para impressionar os usuários. Para manter um equilíbrio entre o grau de otimização e a experiência do usuário, use um designer que ajude bastante.


Link do slide A

segunda ferramenta é o nosso código aberto marciano, sobre o qual prometi falar. Essa coisa é chamada imgproxy e resolve todos os nossos problemas em geral. Nos meus projetos eu uso apenas imgproxy, essa coisa pode fazer quase tudo o que eu quero.



Como funciona? Você tem algum desejo para a foto. Você deseja uma imagem de um determinado tamanho com uma certa otimização. E em algum lugar distante, você tem uma imagem de qualquer resolução - talvez no computador local ou talvez em algum lugar do usuário ou em geral em qualquer lugar. Você só precisa criar um URL especial e pedir ao imgproxy para redimensionar sua imagem. Este é um serviço que pode estar na nuvem ou em outro lugar. Ou seja, você tinha um gato enorme, envia uma URL especial para imgproxy. Ele faz tudo o que você quer na hora.



Se isso não parecer claro, vamos ver como é a solicitação de imgproxy. Primeiro, você precisa dizer onde está localizado o imgproxy. Em segundo lugar, se você não deseja ser agressivamente sugado, o URL que você está solicitando seria bom para assinar digitalmente. Você não pode fazer isso, isso é apenas uma medida adicional de proteção.

Além disso, se você deseja redimensionar, diretamente no URL passe os parâmetros de redimensionamento. Se você deseja otimizar - a mesma coisa. Você só precisa transferir o endereço original da sua foto.



Se você deseja otimizações manuais, há um enorme conjunto de ferramentas. Não vou descrevê-los todos agora. Os materiais para o relatório, que eu enviarei para você, têm tudo.



Aqui está o mais legal e útil. Todas essas imagens não são tão complicadas. Eu acho que consegui transmitir isso para você. Se você estiver interessado, pegue sua linguagem de programação favorita - provavelmente JavaScript, embora esteja longe de ser verdade - e comece a resolver tudo.

Se você quiser fazer isso em um navegador, por favor. Você provavelmente precisa de uma ligação que provavelmente está escrita em vantagens ou em C. Mas o que impede você de compilar tudo isso no WebAssembly? Há um aplicativo interessante chamado Squoosh. Faz exatamente isso. Você também pode, tente, será legal. Eu realmente gosto.

Obrigado a todos pela atenção. Materiais para o relatório - por referência .

All Articles