Quem sou eu e o que este blog.

quinta-feira, 17 de maio de 2012

Por que trabalhar com TIFF, e não JPEG?

Muita gente trabalha com JPEG, salva arquivos intermediários em JPEG, depois carrega de novo e continua o trabalho. Quase ninguém sabe que isto é um erro. Mas por que?

Vou usar no teste a mesma foto usada no artigo JPEG não é compactação, que recomendo ler.


Note: Este artigo é técnico com um certo grau de "nerdice", mas de leitura necessária para muitos. Não precisa entender os scripts que vou colocar, mas eu tenho que colocar por questões de metodologia científica, para mostrar como fiz a experiência, e como pode ser reproduzida. Terão as conclusões de cada experimento, que poderão ser aceitas pelas evidências apresentadas, ou, em caso de dúvida, podem perguntar nos comentários, ou até mesmo tentar reproduzir a experiência.

Definições

Este tópico é de leitura obrigatório aos leigos, necessário para poder entender o resto do artigo.

Script

Script é uma sequência de comandos, um roteiro de execução, que muitas vezes forma um pequeno programa. Muito útil para tarefas repetitivas, como colocar logotipo em uma grande quantidade de fotografias, fazer backup, rotinas de manutenção do sistema etc.

SHA256 e assinatura digital

Existem vários métodos de verificação de dados, como os 2 últimos dígitos do CPF, o dígito de verificação de uma conta bancária etc. Estes dígitos de verificação são criados usando os dados e um fórmula matemática.

O SHA256 é uma fórmula bem complexa para verificação de dados e arquivos. Acredita-se que não existam dois arquivos diferentes com a mesma assinatura por este método, e aparentemente ninguém conseguiu quebrá-lo ainda.

Compactação x compressão

Pela definição que li a muitos anos atrás, a compactação é a redução dos dados, de certa forma simplificando redundâncias, de modo que não se perca nenhuma informação. Métodos de compactação são muito usados com arquivos, e estão embutidos dentro dos programas Winzip, Winrar, GZip etc. Nela não é admitida a perda de dados.

A compressão é diferente. Ela admite alguma perda de dados, para gerar algo mais fácil de compactar. O MP3, o JPEG etc, são assim. Eles são aproximações matemáticas do som, ou da imagem, original, mas são exatamente iguais. Quanto mais perda aceitar, menor pode ficar o arquivo (Seria como jogar fora alguns detalhes.).

Preparação do arquivo inicial

(Leitura opcional, mas aconselhável. É obrigatória para quem se interessar em reproduzir a experiência.)

O arquivo inicial foi gerado pelo meu script de colocação de logotipos. Assim o arquivo JPEG que saiu da câmera foi reduzido e recebeu o logotipo, gerando o arquivo necessário para o resto dos testes. Usei nível de qualidade 95 nesta conversão para JPEG.

Quem quiser reproduzir os testes, pode fazê-lo com qualquer imagem, inclusive a que saiu diretamente da câmera. Cada imagem irá gerar algumas variações no resultado que depende do JPEG, mas não no que só depende do TIFF.

Também pode baixar o arquivo da foto, clicando no botão direito e usando o salvar como, e repetir os meus testes com a mesma imagem, e o mesmo arquivo, que usei. Eu consegui baixar o arquivo, e confirmei a assinatura SHA256 como idêntica ao arquivo original.

Por que usar TIFF?

(Leitura obrigatória.)

O formato de arquivo TIFF pode guardar a imagem original, ou usando métodos de compactação sem perdas, também chamados de "lossless".

O teste consistiu em pegar a imagem inicial, em JPEG, converter para TIFF usando o método padrão (que no caso é sem compactação) dos programas do pacote de conversão usado. Depois converter para TIFF com LZW, depois TIFF com outro método, depois com outro e assim por diante, passando pelo modo de sem compactação, terminando no método padrão de novo.

Se em algum momento do processo, em alguma das conversões, a imagem for modificada, perder algum detalhe, mesmo um bit, então não se reconstituiria no final um arquivo idêntico ao original.

Outro teste feito pelo mesmo script foi converter do TIFF inicial para JPEG, pedindo nível de qualidade 100 (máxima), e depois de novo para TIFF, e verificar se foi gerado o mesmo arquivo, tal como as conversões de TIFF.

O script está abaixo:

#!/bin/sh

# Criado por Joao Rocha Braga Filho para o teste de perdas por recodificacao.

# Arquivo original.
anterior_JPEG=DSC_6173.JPG

jpegtopnm < $anterior_JPEG | tee pam_inicial.pnm | pnmtotiff -truecolor > tiff_inicial.tif
tifftopnm < tiff_inicial.tif | pnmtotiff -truecolor -lzw > tiff_lzw.tif
tifftopnm < tiff_lzw.tif | pnmtotiff -truecolor -flate > tiff_flate.tif
tifftopnm < tiff_flate.tif | pnmtotiff -truecolor -adobeflate > tiff_adobeflate.tif
tifftopnm < tiff_adobeflate.tif | pnmtotiff -truecolor -none > tiff_none.tif
tifftopnm < tiff_none.tif | pnmtotiff -truecolor > tiff_default.tif

echo
echo Convertido de TIFF para TIFF passando por varias compactacoes diferentes.
echo

sha256 tiff_inicial.tif tiff_default.tif

echo

echo Histograma das diferenças entre o original e o final.
echo

tifftopnm < tiff_default.tif > pam_final.pnm
pamarith -difference pam_inicial.pnm pam_final.pnm | ppmhist -nomap

echo
echo Convertido para JPEG e de volta para TIFF.
echo

qualid=100

tifftopnm < tiff_inicial.tif | pnmtojpeg -quality=$qualid | tee tiff_jpeg.jpeg | jpegtopnm | pnmtotiff -truecolor > tiff_posJPEG.tif

sha256 tiff_inicial.tif tiff_posJPEG.tif

echo
echo Histograma das diferenças entre o original e o pós-JPEG.
echo

tifftopnm < tiff_posJPEG.tif > pam_pos-JPEG.pnm

pamarith -difference pam_inicial.pnm pam_pos-JPEG.pnm | ppmhist -nomap

E o resultado pode ser visto abaixo:

goffredo:GoffredoNB2[505] ./TIFF_compactacoes.sh
jpegtopnm: WRITING PPM FILE
pnmtotiff: computing colormap...
tifftopnm: writing PPM file
pnmtotiff: computing colormap...
tifftopnm: writing PPM file
pnmtotiff: computing colormap...
tifftopnm: writing PPM file
pnmtotiff: computing colormap...
tifftopnm: writing PPM file
pnmtotiff: computing colormap...
tifftopnm: writing PPM file
pnmtotiff: computing colormap...

Convertido de TIFF para TIFF passando por varias compactacoes diferentes.

SHA256 (tiff_inicial.tif) = a95552890c967083c4400cb325ec221ad32c1d6a0aff6871a078a1ab7afc1020
SHA256 (tiff_default.tif) = a95552890c967083c4400cb325ec221ad32c1d6a0aff6871a078a1ab7afc1020

Histograma das diferenças entre o original e o final.

tifftopnm: writing PPM file
   r     g     b         lum     count 
 ----- ----- -----      -----   -------
     0     0     0          0    499392

Convertido para JPEG e de volta para TIFF.

tifftopnm: writing PPM file
jpegtopnm: WRITING PPM FILE
pnmtotiff: computing colormap...
SHA256 (tiff_inicial.tif) = a95552890c967083c4400cb325ec221ad32c1d6a0aff6871a078a1ab7afc1020
SHA256 (tiff_posJPEG.tif) = bdf9c35a3e5d71921a5a33d64def92a74ad11bf1fcb3ec59a73f735f992b7f9b

Histograma das diferenças entre o original e o pós-JPEG.

tifftopnm: writing PPM file
   r     g     b         lum     count 
 ----- ----- -----      -----   -------
     0     0     0          0    452482
     1     1     1          1     23459
     1     1     0          1      6510
     0     0     2          0      3866
     2     1     0          1      3854
     1     0     0          0      2346
     0     1     2          1      2098
     2     0     0          1      1504
     0     0     1          0      1077
     0     1     1          1       760
     0     2     1          1       201
     2     0     1          1       182
     1     2     1          2       173
     1     1     2          1       165
     3     0     1          1       126
     2     1     1          1       113
     1     1     3          1       109
     2     1     2          1        96
     1     0     2          1        71
     1     0     3          1        53
     3     1     1          2        40
     2     0     2          1        37
     1     0     1          0        19
     1     2     0          1        19
     1     2     2          2         9
     2     2     2          2         7
     0     1     0          1         6
     0     1     3          1         3
     3     0     3          1         2
     2     0     3          1         2
     1     2     3          2         1
     0     2     0          1         1
     3     1     0          1         1
goffredo:GoffredoNB2[506]

O arquivo inicial e final, depois de várias conversões de formatos TIFF diferentes pelo caminho, tem exatamente a mesma verificação, a mesma assinatura SHA256. Mas quando se passou pelo JPEG intermediário, entre o TIFF inicial e um final, o arquivo não foi mais igual. Mesmo com a qualidade máxima, a imagem foi alterada.

Para tornar mais claro que a imagem foi modificada, o script mostra o histograma da diferença absoluta pixel a pixel das duas imagens. Quando só ficou entre as conversões de TIFFs, no final não houve nenhuma diferença, o que é mostrado no primeiro histograma. Quando passou pelo JPEG houve uma pequena diferença em uma quantidade significativa de pixels. Foram 46910 pixels com pequenas alterações. Se o nível de qualidade fosse menor, certamente as diferenças seriam maiores, e em maior quantidade.

Abaixo está a lista de arquivos gerados neste processo e seus tamanhos:

goffredo:GoffredoNB2[507] ls -ls tiff_*
 832 -rw-r--r--  1 goffredo  users   826681 May 14 02:50 tiff_adobeflate.tif
1488 -rw-r--r--  1 goffredo  users  1498911 May 14 02:50 tiff_default.tif
 832 -rw-r--r--  1 goffredo  users   826681 May 14 02:50 tiff_flate.tif
1488 -rw-r--r--  1 goffredo  users  1498911 May 14 02:50 tiff_inicial.tif
 304 -rw-r--r--  1 goffredo  users   291416 May 14 02:50 tiff_jpeg.jpeg
1088 -rw-r--r--  1 goffredo  users  1096601 May 14 02:50 tiff_lzw.tif
1488 -rw-r--r--  1 goffredo  users  1498911 May 14 02:50 tiff_none.tif
1488 -rw-r--r--  1 goffredo  users  1498911 May 14 02:50 tiff_posJPEG.tif

O JPEG foi o menor, mas teve resultado diferente. Os TIFFs variaram de tamanho, mas sem variar o resultado final.

Conclusões

Portanto o TIFF é um bom formato para se trabalhar, enviar para impressão, editar etc. Nele não se tem perdas de qualidade. O JPEG, por ser menor, pode ter útil para colocar em um site, por exemplo, ou para exibir, quando a mais alta qualidade, ou a perfeição, não são necessárias, pois ele altera o resultado final.

Depois de ler este artigo deve ficar bem mais claro o que aconteceu no cartaz mencionado no artigo O pior cartaz de propaganda que já vi.

Ambiente de teste

(Leitura opcional, só para quem se interessar em reproduzir a experiência.)

As experiências foram conduzidas no meu notebook, rodando FreeBSD 8.2 AMD64, usando o pacote netpbm, compilado à partir dos ports tree. Detalhes podem ser vistos abaixo:

goffredo:GoffredoNB2[490] pkg_info | grep -i netpbm
netpbm-10.35.80_3   A toolkit for conversion of images between different format
goffredo:GoffredoNB2[491] uname -a
FreeBSD GoffredoNB2 8.2-STABLE FreeBSD 8.2-STABLE #9: Tue Jan 31 20:49:06 BRST 2012     root@:/usr/obj/usr/src/sys/NOTEBOOK2  amd64
goffredo:GoffredoNB2[492]

Nenhum comentário:

Postar um comentário