Compressão de Imagem Compreensível

Julius Uy
Julius Uy

Follow

19 de Abril, 2019 – 7 min read

Back nos anos 80, a Microsoft desenvolveu uma solução de rendição de imagem agnóstica de dispositivo para bitmaps: o formato de arquivo BMP.¹ Aqueles que usavam Microsoft Paint antes apreciariam o tamanho gigantesco do arquivo produzido a partir de traçados simples e preenchimentos de cor.

A idéia por trás do formato de arquivo BMP é que a cada pixel é atribuído um valor de cor. Então se eu tivesse um bitmap 480×360 suportando 16 milhões de cores (24 bits), o bitmap acabaria por ser em algum lugar ao norte de 4MB de tamanho.

Figure 1 – A estrutura do arquivo de imagem bitmap (https://en.wikipedia.org/wiki/BMP_file_format)
>

Esta não é, naturalmente, a ideal se se deseja renderizar múltiplas imagens de alta qualidade. Portanto, a pergunta deve ser feita. “Existe uma maneira de otimizar a representação do bitmap de forma que ainda se possa preservar a integridade visual da imagem, mas com menos recursos para usar?”

A resposta é sim. Acontece que, na maioria das vezes, os usuários estão mais interessados em imagens como auxílios visuais do que em profundidade. Por exemplo, suponha que me é dada uma imagem da ponte Golden Gate como mostrado abaixo:

>

Figure 2 – Golden Gate Bridge

Embora eu saiba que a ponte real, quando vista pessoalmente, vem com muito mais detalhes, o que quer que eu veja aqui é suficientemente bom para os seus propósitos. Portanto, a maioria das pessoas estão realmente dispostas a trocar a integridade visual pela velocidade, desde que a troca seja aceitável. Por exemplo, se a degradação na qualidade visual subjetiva é de 1% ainda que o usuário consiga desfrutar de uma economia de espaço de 90%, é na maioria das vezes, uma troca bem-vinda.

Hence, uma das principais considerações na compressão de bitmaps é otimizar para a indistinguibilidade visual. Ou seja, remover certos elementos de uma imagem onde o olho nu é incapaz de identificar a diferença. Isto é chamado de compressão com perdas, que constitui a maioria dos tipos de compressão que se vê no streaming de vídeo em imagens online. É assim que funcionam os codecs H.264, HEVC, HEIF e JPEG.

Figure 3 – Image Compression optimiza a indistinguibilidade visual

Outros tipos de imagens como PNG são compactadas sem perdas. A idéia é que se preserve a integridade visual total da imagem original, mas consumindo bytes menores para representar a mesma coisa. Ainda assim, existem outros formatos de arquivo como o WebP que suporta tanto a compressão com e sem perdas. Por que queremos comprimir as coisas sem perdas? Como acima, ele é baseado no que queremos alcançar para a imagem. Por exemplo, ícones em aplicativos geralmente estão em PNG (e recentemente, em formato de gráficos vetoriais).

Compressão de imagens sem perdas consiste em arquivos de maior tamanho, ao contrário da compressão com perdas. O motivo principal é que existem menos caminhos para comprimir o primeiro do que o segundo. Para os propósitos deste blog, vamos falar sobre compressão com perdas.

Figure 4 – Uma visão geral da compressão JPEG

Os passos gerais dados na compressão JPEG são feitos até hoje na compressão de vídeo. Ao longo dos anos, o algoritmo tem melhorado, mas os conceitos gerais permanecem os mesmos.

STEP 1. Conversão de Espaço de Cor

Conversão de Imagem começa convertendo o formato de imagem RGB bruto para os seus valores Chroma (r e b) e Luminância (Y). A idéia é que nossos olhos são mais sensíveis às mudanças de luminosidade do que à cor. Assim, somos realmente capazes de diminuir a gama de cores na imagem sem afetar notavelmente a qualidade visual da imagem. Isto é feito através da sub-amostragem do Chroma como explicado abaixo.

STEP 2. Chroma Subampling

Muitos jogadores podem se lembrar que a subamostragem está entre os possíveis botões que eles podem definir para otimizar sua experiência de jogo. A idéia principal é que quanto mais sub-amostragem se faz, mais rápido é o desempenho do jogo. Isto porque o jogo requer menos gama de cores para renderizar.

A subamostragem de cores é denotada por J:a:b sendo J o número de pixels para subamostra, a representando os pixels da linha superior e b representando os pixels da linha inferior.

Figure 5 – Subamostragem de Croma

No caso de 4:4:4, significa que em 4×2 pixels, a primeira linha (a) deve ter 4 cores e a segunda linha também. No caso de 4:2:2, significa que em 4×2 pixels, a primeira linha deve ser reproduzida em duas cores e o mesmo acontece com a segunda linha. No caso de 4:2:0, significa que em um 4×2 pixels, a primeira linha deve ser representada por duas cores e a segunda linha copia sobre o que está na primeira linha.

Como você pode ver. através de sub-amostragem de croma, é possível reduzir a gama de cores em até 75%.

STEP 3. Transformação de Coseno Discreto

JPEG compressão é feita cortando a imagem original em um pedaço de 8×8 pixels. Neste passo, atribuímos coeficientes para o trecho 8×8 com base nos sinais mostrados abaixo.

Figure 6 – Transformada Cosina Discreta (DCT). A imagem à esquerda é uma referência de sinal 8×8 usado para lançar peso sobre a imagem original. A imagem da direita é o pedaço resultante após passar por DCT.

A ideia aqui é que à medida que o olho humano se move da parte superior esquerda da referência DCT para a parte inferior direita, mais difícil é de perceber. Então, normalmente, o que acontece é que ao atribuir coeficientes, a parte superior esquerda recebe um valor muito alto e desce à medida que se move para baixo na diagonal.

Aqui está como as coisas podem parecer em formato numérico:

Figure 7 – Parte original (esquerda) Nova parte após a TCD ser aplicada (direita)

STEP 4. Quantização

Após a aplicação do TDC, o próximo passo é chamado de quantização. Aqui, uma tabela de quantização é aplicada aos valores de TDC resultantes. A tabela difere entre algoritmos de compressão e alguns softwares permitem ao usuário definir a quantidade de quantização que deseja usar. Abaixo está uma tabela padrão:

Figure 8 – A Standard Quantization Table

Note que os dígitos vão mais altos à medida que se move da parte superior esquerda para a parte inferior direita. Isto é intencional. A ideia da quantização é que os dados resultantes do TDC são divididos com a tabela de quantização. Aqui é onde a imagem comprimida perde muito se seus dados. Como os números da parte inferior direita são altos, a maioria de seus valores acabará se tornando zero após a divisão. Aqui está como pode parecer:

Figure 9 – Tabela de Quantização (esquerda) Valores resultantes (direita)

STEP 5. Codificação de Entropia usando Codificação Huffman

Codificação Huffman é o último passo na compressão. Aqui está como funciona.

Posto que eu quero representar um intervalo de números usando bits. Além disso, eu quero representá-los de forma que eu consuma a menor quantidade de bits para a representação. Como isso pode ser feito é que os números altamente repetidos recebem bits mais baixos. Por exemplo, se zero for representado em lote, eu geralmente lhe atribuirei bits mais baixos. Uma explicação mais completa da codificação Huffman pode ser encontrada aqui.

A idéia aqui é que você usa menos bits para representar um conjunto mais longo de valores. A codificação Huffman é um algoritmo de compressão sem perdas que também é usado na compressão de arquivos de texto. Fazendo isto, é possível salvar até 50% do tamanho original.

O que se segue?

Compressão é simplesmente uma parte da equação. Quando alguém tem que renderizar a imagem, ele tem que reverter o processo de compressão antes de ser capaz de renderizar a imagem na tela.

JPEGs são cerca de 90% menores do que a sua contraparte bitmap. Até hoje ainda é o formato de compressão de imagem mais popular disponível. Novos algoritmos como HEIF (2013) e AVIF (2018) aumentam a gama de pixels que se pode usar para o algoritmo de compressão.²

Embora o JPEG seja popular, novos formatos oferecem uma melhor compressão. WebP, por exemplo, em geral é cerca de 70% do tamanho do JPEG e ainda assim é capaz de manter a integridade visual da imagem. Assim, o Google (a empresa que desenvolveu o WebP) tem estado a incitar os programadores a recodificar as suas imagens de JPEG para WebP. O suporte para WebP, no entanto, ainda é menor que o JPEG. Portanto, é necessário suportar ambos os formatos como resultado.

¹ “O Formato de Arquivo BMP”. Pré-pressão. Acessado em 19 de abril de 2019. https://www.prepressure.com/library/file-formats/bmp.

² Netflix publicou o primeiro conjunto de imagens AVIF em 2018. A partir deste post, as imagens ainda estão acessíveis aqui. Empresas como Firefox e Microsoft irão suportar esta imagem em breve nas suas ofertas de software.

Deixe uma resposta

O seu endereço de email não será publicado.