bmp文件格式分析
Tag bmp,C语言,二进制,文件读取,格式, on by view 3320

bmp格式图片文件由4部分组成:文件头(BitmapFileHeader),信息头(BitmapInfoHeader),颜色表(RGBQuad),像素矩阵(RGB)[即数据区]。

文件头(BitmapFileHeader)

typedef struct _BITMAPFILEHEADER
{
	BYTE2  bfType;  //类型标识0x4d42
	BYTE4  bfSize;  //文件大小(字节)
	BYTE2  bfReserved1;  //保留1(0)
	BYTE2  bfReserved2;  //保留2(0)
	BYTE4  bfOffBits;  //数据区偏移(字节)
} BitmapFileHeader;

信息头(BitmapInfoHeader)

typedef struct _BITMAPINFOHEADER{ 
	BYTE4  biSize;  //本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为0x28字节=40字节
	BYTE4  biWidth;  //图片宽度(px)
	BYTE4  biHeight;  //图片高度(px)
	BYTE2  biPlanes;  //目标设备的级别(1)
	BYTE2  biBitCount;  //每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一
	BYTE4  biCompression;  //是否压缩(0不压缩)
	BYTE4  biSizeImage;  //图像数据区大小
	BYTE4  biXPelsPerMeter;  //水平分辨率,像素每米
	BYTE4  biYPelsPerMeter;  //垂直分辨率,像素每米
	BYTE4  biClrUsed;  //BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为0x100=256
	BYTE4  biClrImportant;  //重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,
                                //当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色
} BitmapInfoHeader;

颜色表(RGBQuad)

typedef struct _RGBQUAD {
	BYTE1  rgbBlue;  //蓝色分量
	BYTE1  rgbGreen;  //绿色分量
	BYTE1  rgbRed;  //红色分量
	BYTE1  rgbReserved;  //保留(0),非0则为alpha通道
} RGBQuad;

像素

typedef struct _RGBPx
{
	BYTE1  R;  //红色分量
	BYTE1  G;  //绿色分量
	BYTE1  B;  //蓝色分量
} RGBPx;

image_matrix.png

当图像颜色为24位时,即为全彩色RGB模式,无颜色表,所有颜色皆为重要色,因此biBitCount=24时文件中没有RGBQuad区域;若biBitCount为其他值,则图像为索引模式,颜色表中包含图像所用到的颜色,RGBQuad区域为RGBQuad结构体数组。文件中文件头(BitmapFileHeader),信息头(BitmapInfoHeader),颜色表(RGBQuad)三个区域之后是像素矩阵区域。

像素矩阵区中对于24位全色彩文件是RGBQuad区域为RGBQuad结构体数组,对于索引模式图像会将颜色表按照先后顺序编号,例如4位颜色,16色,将会编号0~15号颜色,如此0000b(1)表示第1种颜色,0001b(2),0010b(3),0011b(4),0100b(5)……故一字节可以表示两个像素,如0xa2=10100010b即为11号和2号色。

关于像素矩阵中还有一个问题需要注意,那就是“4字节边界”。像素矩阵的存储是遵循4字节边界存储的,也就是说每一行像素的数据字节大小必须是4的倍数,可是实际上有些图片存储后并不能保证每行的字节数是4的倍数;如一幅1366*768的24位图像,这种图像一像素24位即3字节,则每行1366*3=4098字节,而4098%4=2,余2并不是4的倍数,此时应当在最后2字节后面补充2字节(0x0)。故,在读取时应当注意每行像素后面是否有空边界。

最后,读取的像素还要进行倒置才能够正确的显示,因为原像素矩阵是上下颠倒,左右颠倒的。

paint_picture_reverse_demo.png

最后附上我自己实现的零依赖的bmp解析项目,直接读取二进制bmp文件解析,并带有基础图像变换函数https://github.com/organc/image 。