Análises Profundas

BMP Explicado: O Formato de Imagem Mais Simples do Windows

koboshiCo-founder
·12 min de leitura
BMP Explicado: O Formato de Imagem Mais Simples do Windows
Resumo

O BMP faz parte do Windows desde 1990. Armazena pixels brutos com headers mínimos, sem compressão e sem alpha. Este artigo percorre o formato, do BITMAPFILEHEADER de 14 bytes aos lugares onde ainda aparece, como sistemas embarcados e imagens médicas.

Abra um arquivo BMP num editor hexadecimal e os primeiros catorze bytes são estes:

42 4D 46 00 00 00 00 00 00 00 36 00 00 00

Esse é o BITMAPFILEHEADER por completo. 42 4D é a assinatura "BM" em ASCII. Os quatro bytes seguintes indicam o tamanho do arquivo — 46 00 00 00 equivale a 70 em little-endian. Os quatro seguintes são reservados e sempre zero. Os últimos quatro são o offset para os dados de pixel — 36 00 00 00 é 54, então o array de pixels começa no byte 54.

Nenhum marcador de compressão. Nenhum perfil de cor. Nenhum canal alpha. Só uma assinatura, um tamanho e um offset. O BMP é, como o nome indica, um mapa direto de bits.

O Que é o BMP, na Prática

BMP significa Bitmap, ou, mais formalmente, Device Independent Bitmap (DIB). A Microsoft introduziu-o no Windows 3.0, em 1990, como uma forma de armazenar imagens raster sem amarrá-las a um dispositivo de exibição específico. Antes do DIB, o Windows usava Device Dependent Bitmaps (DDB), cujo formato de pixels correspondia à placa de vídeo instalada. Uma DDB salva numa máquina podia ficar ilegível noutra.

O BMP resolveu isso guardando metadados suficientes para que qualquer decoder reconstruísse a imagem: largura, altura, profundidade de bits, paleta de cores, tipo de compressão e o array de pixels brutos. O sistema operacional lê o header, aloca um buffer e copia os pixels para a memória. Para imagens não comprimidas de 24 bits, os dados de pixel costumam ser triplas RGB escritas de baixo para cima, linha a linha, alinhadas a quatro bytes.

Essa simplicidade fez do BMP o formato de imagem padrão do Windows durante mais de uma década. O Paintbrush, o motor de papel de parede do Windows, scanners antigos e incontáveis ferramentas internas lidavam nativamente com BMP.

A Estrutura do Arquivo

Um arquivo BMP tem quatro partes, dispostas sequencialmente:

BITMAPFILEHEADER   (14 bytes)
BITMAPINFOHEADER   (40 bytes for the classic version)
Color Table        (optional, for indexed color modes)
Pixel Data         (the actual image)

BITMAPFILEHEADER (14 bytes)

Bytes 0-1:   Signature    "BM" (0x42 0x4D)
Bytes 2-5:   FileSize     (uint32, little-endian)
Bytes 6-9:   Reserved     (always 0)
Bytes 10-13: Offset       (uint32, offset to pixel data from file start)

A assinatura nem sempre é "BM". O Windows também suporta "BA", "CI", "CP", "IC" e "PT" para variantes de cursor e ícone, mas na prática todo BMP que você abrir começa com "BM".

BITMAPINFOHEADER (40 bytes, tipo BITMAPINFOHEADER)

Bytes 0-3:   HeaderSize        (40)
Bytes 4-7:   Width             (int32, pixels)
Bytes 8-11:  Height            (int32, pixels; negative means top-down)
Bytes 12-13: Planes            (1)
Bytes 14-15: BitCount          (1, 4, 8, 16, 24, or 32)
Bytes 16-19: Compression       (0 = none, 1 = RLE8, 2 = RLE4, 3 = bitfields)
Bytes 20-23: ImageSize         (0 if uncompressed)
Bytes 24-27: XpixelsPerMeter   (physical resolution)
Bytes 28-31: YpixelsPerMeter   (physical resolution)
Bytes 32-35: ColorsUsed        (0 means 2^BitCount)
Bytes 36-39: ColorsImportant   (0 means all)

Versões posteriores do Windows adicionaram headers maiores — 52, 56, 108 e 124 bytes — para suportar máscaras alpha, espaços de cor e perfis ICC. A versão de 40 bytes ainda é a que você provavelmente encontrará com mais frequência.

A Altura Indica uma Direção

Se o campo de altura for positivo, a imagem é armazenada de baixo para cima. A linha 0 no arquivo é a linha inferior da imagem. Se o campo de altura for negativo, a imagem é armazenada de cima para baixo. Essa é uma das peculiaridades silenciosas do BMP — a maioria dos outros formatos armazena de cima para baixo por padrão.

A Tabela de Cores

Para profundidades de bits de 1, 4 ou 8, o BMP usa uma paleta indexada. Cada entrada da paleta tem quatro bytes: azul, verde, vermelho e um byte alpha reservado que quase sempre é ignorado. Um BMP de 256 cores tem uma tabela de cores de 1.024 bytes imediatamente após o header. Os dados de pixels que seguem não são cores — são índices para essa tabela.

O Preenchimento dos Dados de Pixel

Cada linha de varredura deve ser um múltiplo de quatro bytes. Uma imagem de 24 bits com 5 pixels de largura precisa de 15 bytes por linha, que arredonda para 16. Esses bytes de preenchimento extras são espaço desperdiçado, outro pequeno motivo pelo qual o BMP é ineficiente.

Aqui está um exemplo completo de um BMP não comprimido de 24 bits e 2 x 2:

Offset 0x00: 42 4D 46 00 00 00 00 00 00 00 36 00 00 00  -- BITMAPFILEHEADER
Offset 0x0E: 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18 00  -- BITMAPINFOHEADER
Offset 0x22: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
Offset 0x32: 00 00 00 00 00 00 00 00
Offset 0x36: FF 00 00 00 FF 00 00 00 FF  -- linha inferior: vermelho, verde, azul (com padding)
Offset 0x3F: 00 FF FF 00 FF FF 00 00 00  -- linha superior: ciano, magenta, amarelo (com padding)

O Cenário de Formatos em 1990

O BMP não surgiu do nada. Em 1990, vários formatos de imagem já competiam por espaço:

FormatoCompressãoProfundidade de corTransparênciaRisco de patenteUso típico
GIFLZW256 cores no máximo1 bitSim (LZW)Gráficos web
JPEGDCT + Huffman24 bitsNenhumaNa maioria, nãoFotografias
TIFFMúltiplas opcionaisAté 48 bitsSimOpcionalImpressão, digitalização
PCXRLEAté 24 bitsNenhumaNãoJogos DOS, clip art
PICTRLEAté 32 bitsSimNãoMac OS clássico
BMPNenhuma ou RLEAté 32 bitsNenhumaNãoPapel de parede do Windows, ícones

O GIF já era o padrão na web, mas a patente LZW tornava o uso comercial arriscado. O JPEG foi feito para fotografias e descartava dados com compressão lossy. O TIFF era poderoso, mas superengenheirado — escrever um leitor TIFF universal era um projeto à parte. O PCX morria junto com o DOS.

A proposta do BMP era a simplicidade. Não era menor, mais rápido nem mais capaz que os outros. Era simplesmente o formato que o Windows entendia sem bibliotecas adicionais.

Por Que o BMP Funcionava

O BMP tinha vantagens reais no seu contexto:

Decodificação trivial. Um BMP de 24 bits não comprimido pode ser renderizado lendo um header de tamanho fixo e copiando os pixels diretamente para um framebuffer. Sem tabelas Huffman, sem máquina de estados DEFLATE, sem passes progressivos. Isso o tornava ideal para sistemas embarcados com pouca CPU.

Nenhuma restrição de patente. Ao contrário do LZW do GIF, a compressão no BMP era inexistente ou RLE, ambas livres de patentes. Isso importava para ferramentas open-source e software comercial que queriam evitar a licença de GIF da Unisys.

Integração direta com o Windows. A API Win32 tinha LoadBitmap, BitBlt e StretchBlt construídos em torno de seções DIB. Um desenvolvedor podia carregar um BMP na memória e blitá-lo para a tela em poucas linhas de C.

Layout de memória previsível. Como os pixels de um BMP não comprimido mapeiam diretamente para a memória de vídeo, motores de jogo e ferramentas gráficas o usavam como formato de intercâmbio de texturas nos anos 1990. Era possível mapear o arquivo na memória e tratar o offset de pixels como um buffer bruto.

Onde o BMP Ficou Atrás

Os pontos fortes do BMP também eram suas fraquezas. O formato não acompanhou a evolução do setor.

Nenhuma compressão efetiva. BMPs não comprimidos são enormes. Uma imagem de 1920 × 1080 em 24 bits ocupa 5,93 MB. A mesma imagem como JPEG qualidade 90 fica em cerca de 300–500 KB. À medida que a velocidade da internet e o custo do armazenamento se tornaram gargalos, o BMP passou a parecer inviável.

A compressão RLE é fraca. O BMP suporta RLE8 e RLE4, mas o RLE só ajuda em imagens com grandes áreas uniformes. Fotografias e gradientes comprimem mal. Na prática, BMPs codificados com RLE são raros.

Nenhuma transparência real. O BMP padrão não tem canal alpha. A variante de 32 bits inclui um byte alpha, mas muitas ferramentas o ignoram ou tratam como reservado. Para gráficos web e sprites de jogos, isso tornava o BMP inútil comparado ao PNG.

Sem animação, sem metadados, sem gerenciamento de cor. O BMP guarda pixels e pouco mais. Sem EXIF, sem suporte a perfis ICC no header original, sem frames de animação. Enquanto os fluxos de trabalho ficavam mais sofisticados, o BMP permaneceu primitivo.

Armazenamento de baixo para cima. A ordem padrão de linhas de baixo para cima confunde decoders e desperdiça ciclos de conversão. É um detalhe que gera atrito sem vantagem.

Os Formatos que Substituíram o BMP

As limitações do BMP moldaram diretamente o que surgiu depois.

PNG (1996) resolveu a transparência e a compressão. Oferecia compressão sem perdas, alpha de 8 bits e uma especificação mais simples que a do TIFF. O PNG substituiu o BMP quase em toda a web e em aplicações multiplataforma.

JPEG (1992) resolveu o problema das fotografias. Sua compressão lossy baseada em DCT deixava fotos 10 a 20 vezes menores que um BMP não comprimido. Para imagens de tons contínuos, o JPEG se tornou o padrão.

WebP (2010) adicionou modos com e sem perdas, animação e alpha num único container. Um WebP sem perdas costuma ser 20–30% menor que o PNG, que por sua vez supera o BMP por uma grande margem.

HEIC/HEIF (2013) trouxe compressão baseada em HEVC para imagens estáticas. Consegue arquivos menores que o JPEG com melhor qualidade, suporta alpha e mapas de profundidade, e hoje é o padrão em dispositivos Apple. Quando um iPhone salva uma foto, geralmente é HEIC.

Cada um desses formatos existe porque o BMP deixou de ser suficiente para um caso de uso específico.

Onde o BMP Ainda Aparece

O BMP não desapareceu. Foi apenas relegado a nichos onde sua simplicidade vale mais que sua ineficiência.

Internos do Windows. A tela de boot do Windows, diálogos legados e alguns recursos do sistema ainda usam BMP. A API Win32 GDI espera dados DIB, e reescrever esses caminhos de código não compensa para a Microsoft.

Sistemas embarcados e microcontroladores. Um LCD pequeno num Arduino ou STM32 não tem RAM nem CPU para decodificar PNG. Um BMP de 16 bits não comprimido pode ser copiado diretamente para o framebuffer com quase nenhum código.

Imagens médicas e científicas. Alguns visualizadores DICOM legados e equipamentos de laboratório exportam BMP porque qualquer sistema consegue abri-lo. A simplicidade do formato reduz o risco de interoperabilidade, o que importa em ambientes regulados.

Engenharia reversa e educação. O BMP ainda é um dos melhores formatos para ensinar a estrutura de arquivos de imagem. Os headers são pequenos, o layout de pixels é evidente e dá para construir um decoder funcional numa tarde.

Legado de desenvolvimento de jogos. Motores de jogo e ferramentas de textura mais antigos usavam o BMP como formato intermediário. Algumas comunidades de modding ainda trabalham com assets BMP porque as ferramentas foram feitas em torno dele.

Detectando um BMP Pela Assinatura

Não confie na extensão .bmp. Leia os dois primeiros bytes.

TypeScript

async function isBmp(file: File): Promise<boolean> {
  const buffer = await file.slice(0, 2).arrayBuffer()
  const bytes = new Uint8Array(buffer)
  return bytes.length === 2 && bytes[0] === 0x42 && bytes[1] === 0x4d
}

Python

def is_bmp(path: str) -> bool:
    with open(path, "rb") as f:
        return f.read(2) == b"BM"

Go

func isBmp(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	defer f.Close()

	buf := make([]byte, 2)
	if _, err := f.Read(buf); err != nil {
		return false
	}
	return bytes.Equal(buf, []byte("BM"))
}

PHP

function isBmp(string $path): bool {
    $header = file_get_contents($path, false, null, 0, 2);
    return $header === "BM";
}

CLI do ImageMagick

magick identify -verbose image.bmp | grep "Format:"
# Format: BMP (Microsoft Windows bitmap image)

Ou simplesmente:

file image.bmp
# image.bmp: PC bitmap, Windows 3.x format, 1920 x 1080 x 24

O Futuro do BMP

O BMP é um formato acabado. A especificação principal não mudou de forma significativa desde a era do Windows 95. Isso é ao mesmo tempo uma limitação e uma garantia: um BMP gravado em 1995 ainda abre corretamente hoje.

O formato não ganhará novos recursos. Não terá compressão melhor, tratamento adequado de alpha nem suporte a animação. Ninguém investe em BMP porque ninguém precisa de um BMP melhor. PNG, WebP, AVIF e HEIC já venceram em todos os contextos onde a eficiência importa.

Mas o BMP continuará nos lugares onde já está presente: nos internos do Windows, em telas embarcadas, em equipamentos médicos legados e em salas de aula. É pouco elegante e ineficiente, mas difícil de eliminar porque demasiados sistemas sabem lê-lo.

Se acabar com arquivos BMP legados que precisem funcionar em dispositivos modernos, a solução prática é converter. Para fotografias, converter para JPEG ou HEIC economiza espaço. Para gráficos com transparência, PNG ou WebP são as escolhas certas. E quando precisar de compatibilidade com o ecossistema Apple, converter HEIC para um formato universalmente legível é o primeiro passo.

O nosso conversor de HEIC para JPG funciona inteiramente no navegador — o arquivo nunca sai do seu dispositivo. Para saída sem perdas com transparência, use HEIC para PNG. Para tamanhos otimizados para a web, HEIC para WebP oferece arquivos menores com amplo suporte nos navegadores.

O BMP ensinou à indústria uma lição valiosa: um formato não precisa ser o melhor para estar em toda parte. Só precisa ser simples o suficiente para que todos o implementem, e consolidado o suficiente para que ninguém ouse removê-lo.

Mais posts do blog