Existe una gran variedad de formatos de imágenes tal como BMP, TIFF, GIF, PNG, JPEG, etc. El más sencillo de todos es el formato BMP de 24 bits.
Características:
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 imágenes por ser el mas básico.
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 - tamaño del archivo (en bytes)
4 bytes - Reservados, contienen ceros (reservados para usos futuros)
4 bytes - offset, distancia entre cabecera y píxels (no lo usaremos)
4 bytes - Tamaño de Metadatos (tamaño de esta estructura = 40)
4 bytes - Ancho (numero de píxeles horizontales)
4 bytes - Alto (numero 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 compresión (valdrá 0, ya que es descomprimido)
4 bytes - Tamaño de la estructura Imagen
4 bytes - Píxeles por metro horizontal (No lo usaremos)
4 bytes - Píxeles 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 Estuctura para Visual Basic:
Public Type tipoMetadatosBMP
B As Byte
M As Byte
tamaño As Long
reservado As Long
offset As Long
tamañoMetadatosB
ancho As Long
alto As Long
planos As Integer
profundidadColor As Integer
tipoCompresion As Long
tamañoEstructuraImagen As Long
pixelsPorMetroH As Long
pixelsPorMetroV As Long
cantidadColoresUsados As Long
cantidadColoresImportantes As Long
End Type
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 después de Nuestra cabecera (metadatos), vienen los píxeles (si, esos cuadraditos de colores que conforman nuestra imagen)
Cada Píxel se almacena en 24 bits (3 bytes)
De los 24 bits = 3 bytes, se utilizan 1 byte por cada color básico es decir...
Un byte parta R, Un byte para G, Un byte para B
NO, no son los colores rastas :P, son los colores básicos para el BMP, cada color puede ser obtenido mediante una combinacion 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 razón que desconozco al momento de diseñar 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.Importante!!! :
Ahora ya que al leer los metadatos obtuvimos la resolución (Sí, la RESOLUCIÓN, o sea los píxeles horizontales x verticales)
Además despues de cada fila de pixels (barrido horizontal), si el ancho de
la imagen no es multiplo de 4, se rellena la linea con [ancho mod 4] bytes que
contienen 0.
Por ejemplo si la imagen tuviera 42 pixeles de ancho, se
rellenaria 2 bytes (el resto de 42/4) al final de cada fila de
pixeles.
Recuerdas?
...
ancho As Long
alto As Long
...
ahora podemos leer cada uno de los píxeles de la siguiente manera:
Codigo de ejemplo para leer una imagen en Visual Basic.
Dim meta As tipoMetadatosBMP
Dim i As Long, j As Long, k as Integer, resto as Integer
Dim pixelAux As tipoPixel
Dim relleno as Byte
Open nombreBMP For Binary As #1
Get #1, , meta ' Leemos los metadatos
resto = meta.ancho mod 4 'calculamos el resto
For i = 1 To meta.alto 'Recorremos las filas
For j = 1 To meta.ancho 'Recorremos las columnas
Get #1, , pixelAux 'leemos el pixel ...
Next
For k = 1 To resto 'leemos los pixels de relleno
Get #1, , relleno
Next
Next
Close #1
Asumimos que tenemos declarado el tipo:
Public Type tipoPixel
b As Byte ' Azul
g As Byte ' verde
r As Byte ' rojo
End Type
Codigo 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(); //----------------------------------------------------------
El código es muy similar para cualquier otro lenguaje.
Espero les haya servido.
Comentarios y sugerencias a: carlosagreda-at-gmail.com
miércoles, 6 de febrero de 2008
Destripando un BMP (24 bits)
Publicado por Carlos Agreda en 7:39
Etiquetas: Computación Grafica, Computer Science, Tratamiento Imagenes
Suscribirse a:
Enviar comentarios (Atom)
1 comentario:
Me salvaste la vida gracias por la informacion
Publicar un comentario