Formatos de imagem: WebP

Originalmente, o Google desenvolveu o WebP como um formato de imagem com perda para substituir o JPEG, capaz de produzir arquivos menores que um arquivo de imagem com qualidade comparável codificado como JPEG. Atualizações posteriores do formato introduziram a opção de compactação sem perdas, transparência de canal alfa e animação GIF, que podem ser usadas junto com a compactação com perda no estilo JPEG. WebP é um formato incrivelmente versátil.

O algoritmo de compressão com perda do WebP é baseado em um método que o codec de vídeo VP8 usa para compactar frames-chave em vídeos. De modo geral, ele é semelhante à codificação JPEG: o WebP opera em termos de "blocos" em vez de pixels individuais e tem uma divisão semelhante entre luminância e crominância. Os blocos luma do WebP são 16x16, enquanto os blocos chroma têm 8x8, e esses "macroblocos" são subdivididos em subblocos de 4x4.

Onde o WebP difere radicalmente do JPEG está em dois recursos: "previsão de bloco" e "quantização de bloco adaptável".

Bloquear previsão

A previsão de blocos é o processo pelo qual o conteúdo de cada bloco de crominância e luminância é previsto com base nos valores dos blocos ao redor, especificamente os blocos acima e à esquerda do bloco atual. Como você pode imaginar, os algoritmos que fazem esse trabalho são bastante complexos, mas, em linguagem simples: "se houver azul acima do bloco atual e azul à esquerda do bloco atual, suponha que esse bloco seja azul".

Na verdade, PNG e JPEG também fazem esse tipo de previsão em algum grau. No entanto, o WebP é único, porque faz uma amostra dos dados dos blocos ao redor e, em seguida, tenta preencher o bloco atual usando vários "modos de previsão", tentando efetivamente "desenhar" a parte ausente da imagem. Os resultados fornecidos por cada modo de previsão são comparados aos dados da imagem real, e a correspondência preditiva mais próxima é selecionada.

Um diagrama dos vários métodos de previsão de blocos do WebP.

Mesmo a correspondência preditiva mais próxima não será completamente certa, então, as diferenças entre os valores previstos e reais desse bloco são codificadas no arquivo. Ao decodificar a imagem, o mecanismo de renderização usa os mesmos dados para aplicar a mesma lógica preditiva, levando aos mesmos valores previstos para cada bloco. A diferença entre a previsão e a imagem esperada codificada no arquivo é aplicada sobre as previsões. Isso é parecido com a forma como uma confirmação do Git representa um patch diferencial que é aplicado no arquivo local, em vez de uma cópia totalmente nova do arquivo.

Para ilustrar: em vez de nos aprofundarmos na matemática complexa envolvida no verdadeiro algoritmo de previsão, vamos inventar uma codificação do tipo WebP com um único modo de previsão e usá-la para transmitir uma grade de números de maneira eficiente, da mesma forma que fizemos com os formatos legados. Nosso algoritmo tem um único modo de previsão, que chamaremos de "modo de previsão um". O valor de cada bloco é a soma dos valores dos blocos acima dele e à esquerda dele, começando com 1.

Agora, digamos que estamos começando com os seguintes dados de imagem real:

111151111
122456389

Usando nosso modelo preditivo para determinar o conteúdo de uma grade 2x9, teríamos o seguinte resultado:

111111111
123456789

Nossos dados são adequados para o algoritmo preditivo que criamos: os dados previstos são semelhantes aos de nossos dados reais. Não é uma escolha perfeita, é claro. Os dados reais têm vários blocos diferentes dos dados previstos. Portanto, a codificação que enviamos inclui não apenas o método de previsão a ser usado, mas uma comparação de todos os blocos que devem ser diferentes dos valores previstos:

_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _

Use a mesma linguagem simples de algumas das codificações de formatos legados que discutimos:

Grade 2x9 usando o modo de previsão 1. +4 a 1x5, -1 a 2x3, -4 a 2x7.

O resultado final é um arquivo codificado incrivelmente eficiente.

Quantização de bloco adaptativo

A compressão de JPEG é uma operação geral, que aplica o mesmo nível de quantização a cada bloco da imagem. Em uma imagem com uma composição uniforme, isso certamente faz sentido, mas fotografias do mundo real não são mais uniformes do que o mundo ao nosso redor. Na prática, isso significa que nossas configurações de compactação de JPEG são determinadas não pelos detalhes de alta frequência, em que a compactação de JPEG é excelente, mas pelas partes da imagem em que os artefatos de compactação têm mais chances de aparecer.

Imagem em JPEG compactada de uma borboleta-monarca

Como você pode ver nesse exemplo exagerado, as asas do monarca em primeiro plano parecem relativamente nítidas, um pouco granuladas quando comparadas ao original de alta resolução, mas certamente não perceptíveis sem a imagem original para comparar com a imagem. Da mesma forma, a inflorescência detalhada da seringueira e as folhas em primeiro plano podem ser vistos em primeiro plano. Você e eu podemos ver vestígios de artefatos de compressão com nossos olhos treinados, mas mesmo com a compressão discada bem além dos níveis razoáveis, as coisas em primeiro plano ainda parecem passíveis de nitidez. As informações de baixa frequência no canto superior esquerdo da imagem (o pano de fundo verde borrado das folhas) parecem terríveis. Até mesmo um espectador não treinado percebe imediatamente o problema de qualidade: os gradientes sutis no plano de fundo são arredondados para blocos irregulares e de cor sólida.

Para evitar isso, o WebP adota uma abordagem adaptável em relação à quantização: uma imagem é dividida em até quatro segmentos visualmente semelhantes, e os parâmetros de compactação para esses segmentos são ajustados de maneira independente. Usar a mesma compactação de tamanho extra com o WebP:

Uma imagem WebP compactada de uma borboleta-monarca

O tamanho dos dois arquivos de imagem é quase o mesmo. A qualidade é quase a mesma quando olhamos para as asas do monarca. Você pode notar algumas pequenas diferenças no resultado final se olhar muito de perto, mas nenhuma diferença real na qualidade geral. No WebP, as flores da plantação de leite são apenas um pouco mais nítidas. Mais uma vez, provavelmente não o suficiente para serem perceptíveis, a menos que você esteja comparando as duas lado a lado e realmente procurando diferenças na qualidade, como estamos. O plano de fundo é uma história totalmente diferente: não tem quase nenhum vestígio dos artefatos claramente óbvios de JPEG. O WebP oferece o mesmo tamanho de arquivo, mas uma imagem de qualidade muito maior. Forneça ou inclua alguns pequenos detalhes que nossos sistemas psicovisuais não conseguiriam detectar se não estivéssemos comparando os dois tão de perto.

Como usar o WebP

Os componentes internos do WebP podem ser consideravelmente mais complexos do que a codificação JPEG, mas são simples para o propósito do nosso trabalho diário: toda a complexidade da codificação do WebP é padronizada em torno de um único valor de "qualidade", expresso de 0 a 100, assim como JPEG. Mais uma vez, isso não significa que você esteja limitado a uma única configuração de "qualidade". Você pode e deve mexer em todos os detalhes da codificação WebP para entender melhor como essas configurações normalmente invisíveis podem afetar o tamanho e a qualidade do arquivo.

O Google oferece um codificador de linha de comando cwebp que permite converter ou compactar arquivos individuais ou diretórios inteiros de imagens:

$ cwebp -q 80 butterfly.jpg -o butterfly.webp

Saving file 'butterfly.webp'
File:   butterfly.jpg
Dimension: 1676 x 1418
Output: 208418 bytes Y-U-V-All-PSNR 41.00 43.99 44.95   41.87 dB
        (0.70 bpp)
block count:    intra4:     7644  (81.80%)
               Intra16:     1701  (18.20%)
               Skipped:       63  (0.67%)
bytes used:  header:            249  (0.1%)
              mode-partition:  36885  (17.7%)
Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
macroblocks:     |       8%|      22%|      26%|      44%|   9345
quantizer:       |      27 |      25 |      21 |      13 |
filter level:    |       8 |       6 |      19 |      16 |

E se você não estiver inclinado à linha de comando, o Squoosh também será útil para codificar WebP. Ela oferece a opção de comparações lado a lado entre diferentes codificações, configurações, níveis de qualidade e diferenças de tamanho de arquivo em relação à codificação JPEG.