Sunteți pe pagina 1din 3

Destripando un BMP (24 bits)

Existe una gran variedad de formatos de imgenes tal como BMP, TIFF, GIF, PNG, JPEG, etc. El ms sencillo de
todos es el formato BMP de 24 bits.
Caractersticas:
No es comprimido (Una desventaja con respecto a espacio pero ventaja
por su simplicidad)
Por no ser comprimido es de alta calidad
Se puede ver en cualquier visor de imgenes por ser el ms bsico.
Veamos que hay dentro...

Los Primeros 54 Bytes contienen los metadatos de nuestra imagen y su estructura es la siguiente:
2 bytes - contienen siempre 'BM', para poder identificar que es un bmp
4 bytes - tamao del archivo (en bytes)
4 bytes - Reservados, contienen ceros (reservados para usos futuros)
4 bytes - offset, distancia entre cabecera y pxeles (no lo usaremos)
4 bytes - Tamao de Metadatos (tamao de esta estructura = 40)
4 bytes - Ancho (nmero de pxeles horizontales)
4 bytes - Alto (nmero de pixeles verticales)
2 bytes - Numero de planos de color (No lo usaremos, valdr 1)
2 bytes - Profundidad de color (debe ser 24 para nuestro caso)
4 bytes - Tipo de compresin (valdr 0, ya que es descomprimido)
4 bytes - Tamao de la estructura Imagen
4 bytes - Pxeles por metro horizontal (No lo usaremos)
4 bytes - Pxeles por metro vertical (No lo usaremos)
4 bytes - Cantidad de colores usados (No lo usaremos)
4 bytes - Cantidad de colores importantes (Tampoco usaremos)
Suman 54 bytes, y son los primeros 54 bytes que debemos leer de nuestro archivo.
Podemos leerlo uno a uno pero lo mejor es crear una estructura y leerlos todo de un solo paso.

Ejemplo de estructura para C++:


struct tipoMetadatosBMP
{

char bm[2];
int tamano;
int reservado;
int offset;
int tamanoMetadatos;
int alto;
int ancho;
short numeroPlanos;
short profundidadColor;
int tipoCompresion;
int tamanoEstructura;
int pxmh;
int pxmv;
int coloresUsados;
int coloresImportantes;

};
No debe variar mucho de lenguaje en lenguaje.
Inmediatamente despus de Nuestra cabecera (metadatos), vienen los pxeles (si, esos cuadraditos de colores
que conforman nuestra imagen)
Cada Pxel se almacena en 24 bits (3 bytes)
De los 24 bits = 3 bytes, se utilizan 1 byte por cada color bsico es decir...
Un byte parta R, Un byte para G, Un byte para B
Son los colores bsicos para el BMP, cada color puede ser obtenido mediante una combinacin de R (red), G
(Green) y B (blue).
Considerando que un byte puede almacenar 256 valores diferentes, tenemos:
256 (R) x 256 (G) x 256 colores (B) = 16777216 Colores RGB
Por alguna razn que desconozco al momento de disear el formato los ordenaron BGR y no RGB es decir
primero el byte para azul, luego el byte para verde y luego el byte para verde.

Adems despus de cada fila de pixeles (barrido horizontal), si el ancho de


la imagen no es mltiplo de 4, se rellena la lnea con [ancho mod 4] bytes que
contienen 0.
Por ejemplo si la imagen tuviera 42 pixeles de ancho, se
rellenara 2 bytes (el resto de 42/4) al final de cada fila de
pixeles.
Ahora ya que al leer los metadatos obtuvimos la resolucin (S, la RESOLUCIN, o sea los pxeles horizontales x
verticales)
ahora podemos leer cada uno de los pxeles de la siguiente manera:

Cdigo de ejemplo para leer una imagen en C++


archivo.Open("imagen.bmp",CFile::modeCreateCFile::modeNoTruncateCFile::modeRead);
//cargamos los metadatos ----------------------------------archivo.Read(&bm,2);
archivo.Read(&tamano,sizeof(tamano));
archivo.Read(&reservado,sizeof(reservado));
archivo.Read(&offset,sizeof(offset));
archivo.Read(&tamanoMetadatos,sizeof(tamanoMetadatos));
archivo.Read(&ancho,sizeof(ancho));
archivo.Read(&alto,sizeof(alto));
archivo.Read(&numeroPlanos,sizeof(numeroPlanos));
archivo.Read(&profundidadColor,sizeof(profundidadColor));
archivo.Read(&tipoCompresion,sizeof(tipoCompresion));
archivo.Read(&tamanoEstructura,sizeof(tamanoEstructura));
archivo.Read(&pxmh,sizeof(pxmh));
archivo.Read(&pxmv,sizeof(pxmv));
archivo.Read(&coloresUsados,sizeof(coloresUsados));
archivo.Read(&coloresImportantes,sizeof(coloresImportantes));
//---------------------------------------------------------//Luego leemos los pixeles --------------------------------int resto = metadata.ancho % 4;
for (i=1;i<=metadata.alto;i++)
{

for (j=1;j<=metadata.ancho;j++)
{

archivo.Read(&varB,1); //leemos el byte azul en la variable varB


archivo.Read(&varG,1); //leemos el byte azul en la variable varB
archivo.Read(&varR,1); //leemos el byte azul en la variable varB

}
for (k=1;k<=resto;k++)
archivo.Read(&var,1); //leemos los pixels de relleno
}
archivo.Close(); //----------------------------------------------------------

S-ar putea să vă placă și