Bitmaps
Um bitmap (BMP) é essencialmente o que você descreve, uma matriz de números que representam cores de pixel. Por exemplo, algo como
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
Compressão sem perdas
Agora, vamos definir um esquema de compactação. Em nosso esquema de compactação, teremos uma matriz de pares de números. Por exemplo
3, 1, 1, 0, 7, 1
Agora, a primeira coisa que quero destacar é que esse esquema de compactação representa os mesmos pixels da primeira matriz. A primeira matriz possui três 1s seguidos por um único 0 e depois sete 1s. E é isso que estamos representando aqui. Esse formato é mais curto, pois representa vários pixels com dois números. O formato de bitmap precisa usar um número para cada pixel.
Obviamente, essa é uma visão um pouco simplificada de uma imagem (por exemplo, é apenas uma linha) e um esquema de compactação. Mas espero que isso permita que você veja como um esquema de compactação altera o formato de uma imagem. É assim que um GIF se relaciona a um BMP. O GIF usa um esquema de compactação chamado Lempel-Ziv-Welch em vez deste simplista.
O que descrevemos aqui é um esquema de compactação sem perdas. Um problema com os esquemas de compactação sem perdas é que, para algumas entradas, o formulário codificado pode ser maior que o original. Por exemplo, para
1, 0, 1, 0, 1
A codificação é
1, 1, 1, 0, 1, 1, 1, 0, 1, 1
Bem, isso foi inútil. Fizemos a entrada duas vezes mais.
Outra compressão sem perdas
Agora, vamos considerar um esquema de compactação diferente. Nesta, representaremos a imagem como círculos sobrepostos. Para cada círculo, definiremos um centro, um raio e uma cor.
Nosso primeiro bitmap se tornaria
5, 5, 1, 3, 0, 0
Esse é o mesmo comprimento do nosso primeiro método de compactação.
E o nosso segundo poderia ser
2, 2, 1, 2, 1, 0, 2, 0, 1
São três círculos centralizados no elemento do meio (que na contagem de computadores é o número 2, quando os computadores começam a contar em 0). Um círculo tem raio 2 e cor 1. Em seguida, adicionamos um círculo de cor 0 e raio 1. Finalmente, temos um círculo de cor 1 e raio 0. Em etapas, isso seria
1, 1, 1, 1, 1
1, 0, 0, 0, 1
1, 0, 1, 0, 1
Ou
2, 2, 1, 1, 0, 0, 3, 0, 0
Este é o mesmo círculo inicial, mas coberto por dois círculos de pontos. Em etapas, seria
1, 1, 1, 1, 1
1, 0, 1, 1, 1
1, 0, 1, 0, 1
Ambos são um mais curto que a primeira versão codificada, mas ainda mais que o original.
Você pode se perguntar por que estou falando de círculos e não de intervalos. A principal razão é que os círculos estão mais próximos do que as imagens bidimensionais reais usam.
Compressão com perda
Também temos o conceito de esquemas de compactação com perdas. Esses esquemas de compactação sem perdas podem ser retornados à matriz de bitmap original. Esquemas de compactação com perdas podem não ser reversíveis.
Vamos considerar uma versão com perdas do nosso método de círculos. Nisso, usaremos uma regra simples. Não armazenaremos nenhum círculo com um raio menor que 1. Portanto, em nossas duas últimas codificações, teríamos
2, 2, 1, 2, 1, 0
e
2, 2, 1
que convertidos em pixels novamente são
1, 0, 0, 0, 1
e
1, 1, 1, 1, 1
A primeira versão é apenas um elemento mais longo que o original. A segunda versão é mais curta. Ambos são válidos, portanto o algoritmo é livre para desenvolver os dois e escolher o menor.
Descrevemos imagens com regras mais restritivas como sendo de qualidade inferior.
Essa representação de imagens como coleções sobrepostas de formas circulares é semelhante à maneira como o Joint Photographic Experts Group ou o formato JPEG funciona. Suas formas são elipses e não círculos, mas a idéia é semelhante. Em vez de usar nosso método simplista, ele usa a transformação discreta de cosseno para codificar imagens.
Ao contrário do GIF, o JPEG é realmente uma maneira diferente de representar a imagem. O GIF ainda é pixels. Eles são armazenados apenas de uma maneira diferente. JPEG é formas. Para visualizar um JPEG, convertemos as formas em pixels, porque é assim que as telas funcionam. Em teoria, poderíamos desenvolver uma tela que não funcionasse dessa maneira. Em vez de pixels, poderia produzir formas para corresponder melhor ao formato JPEG. Obviamente, essa tela não seria capaz de mostrar bitmaps. Para exibir um BMP ou GIF, teríamos que converter para JPEG.
Se você converter um GIF padrão, digamos 300 x 300 pixels, convertê-lo em JPEG e diminuir a qualidade, as formas básicas que ele usa deverão ficar visíveis. Muitos JPEGs evitam esses artefatos iniciando com uma imagem de resolução muito maior.
Os JPEGs são bem dimensionados porque são formas e não pixels. Portanto, se você começar com uma imagem de 8000 x 8000, converta-a em JPEG e exiba-a como uma imagem de 300 x 300, muitos dos detalhes perdidos teriam sido perdidos de qualquer maneira. Se você converteu o bitmap de 8000x8000 em um bitmap de 300x300 primeiro e depois em JPEG, os resultados geralmente serão de qualidade inferior.
MPEG
Temos falado sobre imagens estáticas. O formato Moving Picture Experts Group ou MPEG usa o mesmo tipo de compactação que o JPEG, mas também faz outra coisa. Embora uma maneira simples de fazer vídeo seja enviar uma sequência de imagens estáticas, o MPEG envia um quadro, seguido por um número de quadros listando as alterações e finalizando com um quadro final. Como a maioria dos quadros é semelhante ao quadro anterior, a lista de alterações geralmente é menor que uma segunda imagem.
A sequência normalmente não é tão longa, digamos cinco quadros. Mas isso ajuda a tornar o fluxo menor do que seria.
Simplificações
Eu ignorei muito. Minhas imagens têm apenas duas cores (1 bit), não as 256 de uma imagem de 8 bits e certamente não as 4.294.967.296 de uma imagem de 32 bits. Mesmo com imagens de 8 bits, observe que muitas vezes você pode escolher paletas diferentes para a imagem. Portanto, dois bitmaps de 8 bits com as mesmas seqüências podem representar imagens com aparência diferente (mesma forma, mas cores diferentes).
Minhas imagens são linhas únicas, não bidimensionais. A maioria das imagens terá um tamanho de linha específico armazenado, tornando as matrizes bidimensionais.
Não tentei representar as codificações reais. Eles são muito mais complexos do que os simples que eu usei. Fiz isso porque queria poder descrever as codificações neste post. Não estou convencido de que poderia explicar Lempel-Ziv muito menos o refinamento mais complexo de Lempel-Ziv-Welch em uma única resposta. E eu não entendo que Fourier se transforma bem o suficiente para explicá-las de qualquer maneira.
Essa é uma versão simplificada do manuseio real de imagens. No entanto, sinto que, para fins didáticos, é mais fácil entender do que a realidade mais complexa, enquanto ainda atinge os pontos essenciais.