BMP: Bitmap de Windows como Fundamento de Gráficos Raster
El formato BMP (Bitmap) es el formato de imagen raster nativo sin comprimir de Windows—posiblemente el formato de imagen más simple jamás estandarizado, con sobrecarga de procesamiento casi nula. Aunque el uso moderno es limitado (JPEG, PNG vastamente superiores), BMP sigue siendo importante para: sistemas embebidos con recursos computacionales mínimos, hardware de imagen médica/industrial heredado y como referencia pedagógica para entender estructura raster sin procesar.
Estructura de Archivo BMP: Encabezado de Archivo y Encabezado DIB
Cada archivo BMP contiene dos encabezados:
Encabezado de Archivo (14 bytes):
[Firma: 2 bytes ('BM' = 0x42 0x4D)]
[Tamaño Archivo: 4 bytes (little-endian)]
[Reservado: 4 bytes (0x00000000)]
[Desplazamiento: 4 bytes (desplazamiento byte a datos píxel)]
Encabezado DIB (tamaño variable, típicamente 40 u 108 bytes): Más común: BITMAPINFOHEADER (40 bytes):
[Tamaño Encabezado: 4 bytes (40 para esta variante)]
[Ancho: 4 bytes (firmado, píxeles)]
[Alto: 4 bytes (firmado, píxeles; negativo = de arriba a abajo)]
[Planos Color: 2 bytes (siempre 1)]
[Bits Por Píxel: 2 bytes (1, 4, 8, 16, 24, 32)]
[Compresión: 4 bytes (0=sin comprimir, 1=RLE-8, 2=RLE-4)]
[Tamaño Imagen: 4 bytes (en bytes; puede ser 0 para sin comprimir)]
[Resolución Horizontal: 4 bytes (píxeles por metro)]
[Resolución Vertical: 4 bytes (píxeles por metro)]
[Colores Usados: 4 bytes (0 = predeterminado para profundidad bits)]
[Colores Importantes: 4 bytes (0 = todos los colores)]
[Tabla Color Opcional: variable (entradas paleta si profundidad bits ≤ 8)]
[Datos Píxel: variable]
Ejemplo: BMP 8-bit mínimo de 1×1:
Encabezado Archivo:
42 4D (firma BM)
3A 00 00 00 (tamaño archivo = 58 bytes)
00 00 00 00 (reservado)
36 00 00 00 (desplazamiento a datos píxel = 54 bytes después encabezados)
Encabezado DIB (BITMAPINFOHEADER):
28 00 00 00 (tamaño encabezado = 40)
01 00 00 00 (ancho = 1 píxel)
01 00 00 00 (alto = 1 píxel)
01 00 (planos = 1)
08 00 (bits por píxel = 8)
00 00 00 00 (compresión = ninguna)
00 00 00 00 (tamaño imagen = calculado por decodificador)
13 0B 00 00 (72 DPI horizontal = 2835 píxeles/metro)
13 0B 00 00 (72 DPI vertical)
00 00 00 00 (colores usados = predeterminado para 8-bit)
00 00 00 00 (colores importantes = todos)
Paleta Color (8-bit: 256 entradas × 4 bytes cada = 1024 bytes):
[R, G, B, Reservado] para cada color...
Datos Píxel (1 píxel, 8-bit indexado):
00 (valor píxel = índice tabla color 0)
Profundidades de Color y Codificación: 1-Bit a 32-Bit
| Profundidad | Tipo | Colores | Empaquetamiento | Ejemplo Tamaño Archivo (1 MP) |
|---|---|---|---|---|
| 1-bit | Bilevel | 2 (B&N) | 8 px/byte | ~125 KB |
| 4-bit | Paleta indexada | 16 | 2 px/byte | ~250 KB |
| 8-bit | Paleta indexada | 256 | 1 px/byte | ~1 MB |
| 16-bit | RGB555 o RGB565 | 32K o 64K | 2 bytes/píxel (empaquetado) | ~2 MB |
| 24-bit | RGB color verdadero | 16.7M | 3 bytes/píxel (orden B, G, R) | ~3 MB |
| 32-bit | RGBA (con alfa) | 16.7M + transparencia | 4 bytes/píxel | ~4 MB |
Nota de codificación de píxel: BMP almacena píxeles en orden de abajo a arriba (de izquierda a derecha, fila inferior primero) a menos que la altura sea negativa.
Paleta de Color: Color Indexado para Imágenes 1-, 4-, 8-Bit
Para profundidades paletizadas (1-, 4-, 8-bit), BMP incluye una tabla de color inmediatamente después del encabezado:
8-bit: 256 entradas × 4 bytes (R, G, B, Reservado) = 1024 bytes
4-bit: 16 entradas × 4 bytes = 64 bytes
1-bit: 2 entradas × 4 bytes = 8 bytes
Cada valor píxel es un índice en esta tabla. Ejemplo:
- Valor píxel
42en imagen 8-bit → tabla color[42] = (255, 128, 0) = naranja - Valor píxel
5en imagen 4-bit → tabla color[5] = (0, 0, 255) = azul
Compresión RLE: Codificación de Longitud de Ejecución
BMP soporta RLE (Run-Length Encoding) opcional para imágenes 4- y 8-bit:
Comprimido: [Escape (0x00), Conteo (1 byte), Valor (1 byte), ...]
Sin comprimir: [0x00, 0x00] (marcador fin de línea)
RLE es efectivo para imágenes sintéticas (diagramas, escaneos) con grandes bloques de color; inefectivo para contenido fotográfico.
Ejemplo RLE 8-bit (10 píxeles rojos consecutivos):
0A FF (10 copias del índice color 255 = rojo)
Variantes BMP: BITMAPCOREHEADER, BITMAPV4HEADER, BITMAPV5HEADER
- BITMAPCOREHEADER (12 bytes): Variante más antigua; ancho/alto almacenados como enteros de 2 bytes (máx. 65K)
- BITMAPINFOHEADER (40 bytes): Estándar; ancho/alto como firmado de 4 bytes (soporta altura negativa para de arriba a abajo)
- BITMAPV4HEADER (108 bytes): Añade espacio de color (sRGB, Adobe RGB, perfil ICC personalizado) y máscara alfa
- BITMAPV5HEADER (124 bytes): Añade intención de renderizado y metadatos HDR (raramente usado)
Limitaciones de BMP y Alternativas Modernas
Debilidades de BMP:
- Sin compresión (de forma predeterminada): Imagen 1 MB → archivo BMP 3–4 MB (vs. 50–200 KB JPEG)
- Escanlines de abajo a arriba: No estándar; complica decodificadores de streaming
- Gestión pobre de color: Los encabezados DIB no tienen soporte de perfil ICC nativo (BITMAPV4/V5 abordan parcialmente esto)
- Metadatos limitados: Sin soporte EXIF, IPTC o XMP
- Sin entrelazado: No puede mostrar escaneos progresivos mientras se descarga
Reemplazos modernos:
- PNG: Compresión lossless, transparencia, perfiles ICC, entrelazado, compresión superior
- JPEG: Compresión con pérdidas, excelente para fotografías, 10–50× más pequeño que BMP sin comprimir
- WebP: Compresión moderna (lossless y lossy), más pequeño que PNG/JPEG, buen soporte de navegador
Procesamiento de BMP: Python, Bibliotecas C, ImageMagick
Python (PIL/Pillow):
from PIL import Image
# Cargar BMP
img = Image.open('foto.bmp')
print(f"Tamaño: {img.size}, Modo: {img.mode}") # Modo: 'RGB', 'RGBA', 'L', 'P', etc.
# Convertir a PNG (comprimir)
img.save('foto.png') # Reducción tamaño típica ~90%
# Convertir paleta a RGB
if img.mode == 'P':
img = img.convert('RGB')
img.save('convertido.bmp')
ImageMagick:
# BMP → PNG (comprimir)
convert foto.bmp foto.png
# BMP → JPEG (con pérdidas, más pequeño)
convert foto.bmp -quality 85 foto.jpg
# Convertir directorio por lotes
mogrify -format png *.bmp
Biblioteca C (libbmp vía FFI):
#include <stdio.h>
// Lectura/escritura BMP específica de plataforma (API mínima, deprecada a favor de libpng/libjpeg)
Comparación: BMP vs PNG, JPEG, TIFF, WebP
| Aspecto | BMP | PNG | JPEG | TIFF | WebP |
|---|---|---|---|---|---|
| Compresión | Ninguna (o RLE) | Lossless (Deflate) | Con pérdidas (DCT) | Opcional (LZW, JPEG, ninguna) | Lossless/con pérdidas |
| Tamaño archivo | Más grande (~1 MB por MP) | Pequeño (~200 KB por MP) | Muy pequeño (~50 KB por MP) | Medio (300 KB–1 MB) | Pequeño (~100 KB por MP) |
| Transparencia | Alfa de 32-bit | Sí (alfa de 8-bit) | No | Sí (vía recorte) | Sí (alfa de 8-bit) |
| Metadatos | Mínimos (solo DPI) | Chunks (EXIF vía chunk) | Marcadores (EXIF, IPTC) | Extensos (etiquetas IFD) | Mínimos |
| Gestión color | Espacio color DIB (BITMAPV4+) | Perfil ICC (chunk) | Marcadores limitados | Perfil ICC extenso | Sí (VP8 CICP) |
| Entrelazado | No | Sí (Adam7) | No (progresivo línea base) | No (TIFF piramidal) | Sí (vista previa VP8) |
| Soporte navegador | Universal | Universal | Universal | Pobre (requiere plugin) | Bueno (moderno) |
| Calificación archivo | Pobre (sin comprimir) | Excelente | Aceptable (artefactos con pérdidas) | Excelente | Desconocida |
Cuándo Elegir BMP
- Sistemas embebidos: Sobrecarga mínima de CPU; decodificable en firmware
- Hardware heredado: Sistemas médicos/control industrial aún esperan BMP
- Propósitos pedagógicos: Aprender estructura raster; formato de imagen más simple
- Evitar BMP si: Entrega por internet (usar PNG/JPEG/WebP), compresión necesaria, metadatos requeridos, software moderno (prefiere PNG)
BMP está deprecado para prácticamente todos los casos de uso modernos pero sigue siendo una referencia fundamental para entender codificación raster sin procesar—pixel-perfecto pero ineficiente.
Conversiones relacionadas
Conversiones frecuentes del catálogo: