BMP 储存个人理解
<第一部分>位图文件头BITMAPFILEHEADER,此结构长度固定占14字节
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
变量 | 大小(共14字节) | 作用 |
bfType | 2bytes |
文件类型说明,可取值: BM - windows 3.1x,95,NT,... BA - OS/2 Bitmap Array CI - OS/2 Color Icon CP - OS/2 Color Pointer IC - OS/2 Icon PT - OS/2 Pointer |
bfsize | 4bytes | 说明文件大小,单位:byte |
bfReserved1 | 2bytes | 保留,必须设置为0 |
bfReserved2 | 2bytes | 保留,必须设置为0 |
bfOffBits | 4bytes |
说明从文件头到实际图像数据之间的字节偏移量。 因为位图信息头和调色板的长度不是固定的,有助于迅速定位位图数据 |
<第二部分>为位图信息头BITMAPINFOHEADER,也是一个结构,其定义如下:
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;
变量 | 大小 | 作用 |
biSize | 4 bytes | BITMAPINFOHEADER结构需要的字节数 |
biWidth | 4 bytes | 图像宽度,像素为单位 |
biHeight | 4 bytes |
图像高度,像素为单位 注:如果该值为正数,说明图像是倒向的;为负数,图像是正向的 大多数bmp图像是倒向的位图; |
biPlanes | 2 bytes | 为目标设备说明颜色平面数,值为1 |
biBitCount | 2 bytes | 说明比特数/像素,为1,4,8,16,24或32 |
biCompression | 4 bytes |
说明图像数据压缩类型,取值范围: 0 BI_RGB 不压缩 1 BI_RLE8 8比特游程编码(RLE),只用于8位位图 2 BI_RLE4 4比特游程编码(RLE),只用于4位位图 3 BI_BITFIELDS 比特域,用于16/32位位图 4 BI_JPEG JPEG位图含jpeg图像(仅用于打印机) 5 BI_PNG PNG位图含png图像(仅用于打印机) |
biSizeImage | 4 bytes | 说明图像大小 biSizeImage=biWidth’ × biHeight,单位字节,当用BI_RGB时,可设置为0 |
biXPelsPerMeter | 4 bytes | 说明水平分辨率(像素/米),有符整数 |
biYPelsPerMeter | 4 bytes | 说明垂直分辨率(像素/米),有符整数 |
biClrUsed | 4 bytes | 说明位图实际使用的色彩表中的颜色索引,为0看后续说明 |
biClrImportant | 4 bytes | 说明对图像显示有重要影响的颜色索引数目,为0表示都重要 |
<第三部分>为调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。有些位图,如真彩色图,前面已经讲过,是不需要调色板的,BITMAPINFOHEADER后直接是位图数据。可以理解为biClrUsed参数不为0时,有调色板。
调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2biBitCount个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:
typedef struct tagRGBQUAD {
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值
} RGBQUAD;
比如索引值biClrUsed为64,即有64个调色盘,则总偏移量计算14bytes+40bytes+64*4bytes=310bytes
<第四部分>实际的图象数据。
(1)对于用到调色板的位图,图象数据就是该象素颜在调色板中的索引值。即某一点只储存一个索引值,按照这个索引值在调色板中查找对应像素作为它的像素
(2)对于真彩色图,图象数据就是实际的R、G、B值。下面针对2色、16色、256色位图和真彩色位图分别介绍。 每个像素点都是按调色板的格式储存的,也可以理解为全是调色板
对于2色位图,用1位就可以表示该象素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个象素。
对于16色位图,用4位可以表示一个象素的颜色,所以一个字节可以表示2个象素。
对于256色位图,一个字节刚好可以表示1个象素。
要注意两点:
(1) 每一行的字节数必须是4的整倍数,如果不是,则需要补齐。这在前面介绍biSizeImage时已经提到了。
(2) 一般来说,.BMP文件的数据从下到上,从左到右的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个象素,然后是左边第二个象素……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推 ,最后得到的是最上面一行的最右一个象素。
<对齐>
Windows默认的扫描的最小单位是4字节,如果数据对齐满足这个值能够大幅提升图像读取速度。因此,BMP图像顺应了这个要求,要求每行的数据的长度必须是4的倍数,如果不够需要进行比特填充(以0填充)。填充后的每行的字节数为:rowsize=4*ceil(BPP*Width/32)
<其他情况>
上述主要是PC机上的位图文件的构成,对于嵌入式平台,可能在调色板数据段与PC机的不同。如在嵌入式平台上常见的16位r5g6b5位图实际上采用的掩模的方式而不是索引的方式来表示图像。此时,在调色板数据段共有四个部分,每个部分为四个字节,实际表示的是彩色版规范。即:
第一个部分是红色分量的掩模
第二个部分是绿色分量的掩模
第三个部分是蓝色分量的掩模
第四个部分是Alpha分量的掩模(缺省为0)
1111100000000000(二进制),是蓝红分量的掩码。
0000011111100000(二进制),是绿色分量的掩码。
0000000000011111(二进制),是蓝色分量的掩码。
在每个像素值的两个字节16位中,按从高到低取5、6、5位分别就是r、g、b分量值;把分量值r、g、b值分别左移操作3、2、3位就可以补齐每个分量为一个字节,再把这三个字节按BGR组合,就可以转换为24位标准BMP格式