BMP文件格式解析
位图文件(Bitmap-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格式。BMP位图文件默认的文件扩展名是bmp或者dib。BMP文件大体上分为四个部分:
位图文件头
主要包括:
- typedef struct tagBITMAPFILEHEADER {
- WORD bfType;
- DWORD bfSize;
- WORD bfReserved1;
- WORD bfReserved2;
- DWORD bfOffBits;
- } BITMAPFILEHEADER;
位图信息头
主要包括:
- typedef struct tagBITMAPINFOHEADER {
- DWORD biSize;
- LONG biWidth;
- LONG biHeight;
- WORD biPlanes;
- WORD biBitCount;
- DWORD biCompression;
- DWORD biSizeImage;
- LONG biXPelsPerMeter;
- LONG biYPelsPerMeter;
- DWORD biClrUsed;
- DWORD biClrImportant;
- } BITMAPINFOHEADER;
调色板
实际上是一个数组,它所包含的元素与位图所具有的颜色数相同,决定于biClrUsed和biBitCount字段。数组中每个元素的类型是一个RGBQUAD结构。真彩色无调色板部分。
- typedef struct tagRGBQUAD {
- BYTE rgbBlue;
- BYTE rgbGreen;
- BYTE rgbRed;
- BYTE rgbReserved;
- } RGBQUAD;
紧跟在调色板之后的是
图像数据字节阵列
。对于用到调色板的位图,图像数据就是该像素颜色在调色板中的索引值(逻辑色)。对于真彩色图,图像数据就是实际的R、G、B值。图像的每一扫描行由表示图像像素的连续的字节组成,每一行的字节数取决于图像的颜色数目和用像素表示的图像宽度。规定每一扫描行的字节数必需是4的整倍数,也就是DWORD对齐的。扫描行是由底向上存储的,这就是说,阵列中的第一个字节表示位图左下角的像素,而最后一个字节表示位图右上角的像素。
读取BMP文件,提取RGB数据的流程
流程如下图所示:
在这里需要注意的的是,根据BMP每像素所占的比特数不同(8,16,32 bpp),分为不同的处理方法,如下图所示。
下面看看16bpp的BMP文件操作:
R,G,B在16bit中所占的位数如下图所示
- for (Loop = 0;Loop < height * width;Loop +=2)
- {
- *rgbDataOut = (Data[Loop]&0x1F)<<3;
- *(rgbDataOut + 1) = ((Data[Loop]&0xE0)>>2) + ((Data[Loop+1]&0x03)<<6);
- *(rgbDataOut + 2) = (Data[Loop+1]&0x7C)<<1;
- rgbDataOut +=3;
- }
1-8bpp的BMP文件操作:
- int shiftCnt = 1;
- while (mask)
- {
- unsigned char index = mask == 0xFF ? Data[Loop] : ((Data[Loop] & mask)>>(8 - shiftCnt * info_h.biBitCount));
- * rgbDataOut = pRGB[index].rgbBlue;
- * (rgbDataOut+1) = pRGB[index].rgbGreen;
- * (rgbDataOut+2) = pRGB[index].rgbRed;
- if(info_h.biBitCount == 8) mask = 0;
- Else mask >>= info_h.biBitCount;
- rgbDataOut+=3;
- shiftCnt ++;
- }