Trilha 16 · Imagens, áudio e vídeo

Compressão de imagem

Como JPEG e PNG reduzem imagens em 10–100× — quantização no domínio de frequência, chroma subsampling, e a diferença fundamental entre compressão com e sem perdas.

① Intuição

O olho humano como aliado

Uma foto Full HD tem 1920×1080 = 2.073.600 pixels, cada um com 3 bytes (RGB) = 6 MB. Um arquivo JPEG típico da mesma foto ocupa 300–500 KB — uma compressão de 10–20×. Como é possível sem que o resultado pareça completamente diferente?

O segredo é explorar as limitações do sistema visual humano. O olho é muito mais sensível a diferenças de brilho do que de cor. E mais sensível a variações lentas (baixas frequências espaciais) do que a detalhes finos (altas frequências). JPEG descarta justamente o que o olho menos percebe.

Compressão com perdas vs. sem perdas: JPEG é lossy — a imagem decodificada difere da original. PNG é lossless — decodificar PNG devolve exatamente os pixels originais. WebP e AVIF suportam ambos os modos. A escolha depende do uso: fotos (JPEG/lossy), logos e screenshots (PNG/lossless).
② Visualização interativa

Quantização de cor

Reduza os bits por canal e veja os artefatos de "banding" aparecerem. JPEG faz algo similar mas no domínio de frequência (via DCT) em vez de no domínio de pixel.

ORIGINAL — 8 bits/canal
3072 bytes · 16.777.216 cores
QUANTIZADO — 8 bits/canal
3072 bytes · 16.8M cores
Bits por canal (profundidade de cor)8 bits256 valores por canal
1 bit (2 cores)4 bits (4.096 cores)8 bits (16.7M)
RAZÃO
1.0:1
REDUÇÃO
0%
PSNR
dB
PSNR (Peak Signal-to-Noise Ratio): acima de 40dB → quase imperceptível; 30–40dB → bom; abaixo de 30dB → artefatos visíveis.
③ Explicação técnica

O pipeline JPEG

// JPEG: pipeline de compressão simplificado

// 1. Converter RGB → YCbCr (separar luminância de crominância)
const Y  =  0.299*R + 0.587*G + 0.114*B;
const Cb = -0.169*R - 0.331*G + 0.500*B + 128;
const Cr =  0.500*R - 0.419*G - 0.081*B + 128;

// 2. Chroma subsampling 4:2:0
// Y (luminância): resolução completa → olho muito sensível ao brilho
// Cb, Cr: metade da resolução → olho menos sensível à cor
// Economia: de 3 bytes/px para 1.5 bytes/px (50% menor!)

// 3. Para cada bloco 8×8 de pixels:
//    a. Aplicar DCT (Transformada Discreta de Cosseno)
//    b. Dividir coeficientes pela tabela de quantização (qualidade)
//    c. Arredondar para inteiro (PERDA de informação!)
//    d. Codificar com Huffman (sem perdas)

// Coeficiente DC (0,0) = média do bloco — preservado com mais precisão
// Coeficientes AC (altas frequências, canto inferior direito) — mais quantizados

// 4. Reconstrução (decodificação)
// coef_real = coef_quantizado × tabela_quantizacao
// IDCT → blocos de pixels → juntar blocos → YCbCr → RGB

PNG: compressão sem perdas

// PNG: compressão sem perdas (lossless)

// 1. Filtros de predição (reduzem entropia antes de comprimir)
// Para cada linha de pixels, escolhe o melhor filtro:
//   None:  pixel atual sem modificação
//   Sub:   pixel - pixel_esquerda
//   Up:    pixel - pixel_acima
//   Avg:   pixel - média(esq, cima)
//   Paeth: pixel - preditor de Paeth (escolhe o melhor dos 3)

// Para uma imagem com gradiente suave, Sub ou Up geram
// muitos zeros — fáceis de comprimir!

// 2. DEFLATE (compressão)
//    = LZ77 (dicionário de sequências repetidas)
//    + Huffman (codificação dos símbolos)

// PNG não perde informação — decodificado = original exato
// JPEG perde — decodificado tem artefatos de bloco (blocking)
// Use PNG para: logos, screenshots, arte pixel, ícones
// Use JPEG para: fotos onde artefatos são imperceptíveis
Blocking artifacts (artefatos JPEG): nas bordas de qualidade JPEG baixa, você vê "quadradinhos" de 8×8 pixels. Isso acontece porque cada bloco 8×8 é comprimido independentemente — com quantização agressiva, os coeficientes DCT ficam tão arredondados que blocos adjacentes ficam visivelmente descontinuados. Algoritmos modernos como HEIF (iPhone) e AVIF minimizam isso com blocos maiores (até 64×64) e compressão intra-bloco mais sofisticada.
④ Projeto para programar

Manipulação de imagem com Canvas

Mini projeto: aplique um filtro de desfoque (blur) em uma imagem no Canvas: para cada pixel, calcule a média dos N×N pixels ao redor. Teste com N=3, 5, 7. Observe como aumentar N suaviza a imagem progressivamente.

Projeto principal: implemente detecção de bordas com o operador Sobel: calcule o gradiente horizontal (Gx) e vertical (Gy) usando convolução 3×3, e marque como borda os pixels onde sqrt(Gx² + Gy²) > threshold. O resultado deve mostrar as bordas da imagem em branco sobre fundo preto.

Desafio extra: implemente uma versão simplificada de compressão DCT para blocos 4×4 (em vez de 8×8): aplique DCT 2D, zere os coeficientes de alta frequência (canto inferior direito), aplique IDCT e compare com o original. Quantifique o erro com PSNR.

⑤ Exercícios rápidos

Teste sua intuição

Como JPEG comprime imagens com perdas?
O que é chroma subsampling (4:2:0) e por que funciona?
Como PNG consegue compressão sem perdas?
⑥ Aplicações no mundo real

Onde você encontra isso

📷

Formatos modernos: WebP e AVIF

WebP (Google, 2010) usa predição intra-bloco (como H.264) em vez de DCT, conseguindo 25–34% menor que JPEG na mesma qualidade. AVIF (2019) é baseado em AV1 e consegue 50% menor que JPEG. Todos os browsers modernos suportam ambos. Use <picture> com fallback para JPEG.

🌐

Performance web

Imagens representam 50–60% do peso de páginas web típicas. Ferramentas como Squoosh, ImageOptim e Cloudinary aplicam JPEG/WebP otimizado automaticamente. O parâmetro "quality" do JPEG não é padronizado — JPEG quality=85 de Photoshop ≠ quality=85 do ImageMagick.

🏥

Imagens médicas (DICOM)

Radiografias, CTs e MRIs usam o formato DICOM com compressão sem perdas (JPEG-LS ou JPEG 2000 lossless). Compressão com perdas é proibida em imagens de diagnóstico — um artefato de 8×8 pixels numa mamografia pode ser confundido com uma lesão ou ocultar uma.

← Anterior: Síntese de Fourier Próxima: Codificação de Huffman →