BMP文件格式分析

/ 0评 / 0

BMP文件分析有助于用MCU解码BMP文件.24位样图:

QQ截图20150922125407

我们使用HEX方式打开.发现如下:

QQ截图20150922125726

首先,0x42,0x4D,就是BM,证明这是一个BMP文件.

QQ截图20150922130000

大小如图:

QQ截图20150922131819

读法按照LE方式,就是0x000000f6,就是246字节,看看Windows识别图.

QQ截图20150922132045

实际数据偏移是0x00000036.

QQ截图20150922135355

高亮字符为数据开始处:

QQ截图20150922135537

下图高亮处表示图像头占用长度0x00000028

QQ截图20150922135813

下图高亮而且红框内是图像的宽度,不是红框且高亮的是图像高度.

QQ截图20150922135936

使用彩色平面数0x0001,所有BMP都是这个数值,貌似.

QQ截图20150922140106

色深就是0x0018,换过来就是24位深了:

QQ截图20150922140403

图像掩码,这张图是全部颜色表示,所以是全零.

QQ截图20150922140702

接下来看到实际像素占用0x000000C0,就是192,和我们之前的246,不一样.这个是从数据开始算的.

QQ截图20150922141144

接着是水平像素,就是每米像素多少,估计是为了100%比例来还原图像的,红框外的是垂直像素.

QQ截图20150922141021

位图中实际使用的颜色表中的颜色数:

QQ截图20150922141314

位图中重要颜色数量:

QQ截图20150922141421

然后按左下到右上顺序刷,如下序列:

QQ截图20150922141625

3个字节一个,例如这个绿色:

QQ截图20150922142057

其中4C就是蓝色76,B1就是绿色177,22就是红色34.颜色差别太小,人是看不出来的.我们用C语言来表示,就是由两部分组成.其实计算实际偏移量的时候,已经是第一部分结束,所以是这样的:

//BMP头文件
typedef __packed struct
{
    uint16_t  bfType ;     //文件标志.只对'BM',用来识别BMP位图类型
    uint32_t  bfSize ;	  //文件大小,占四个字节
    uint16_t  bfReserved1 ;//保留
    uint16_t  bfReserved2 ;//保留
    uint32_t  bfOffBits ;  //从文件开始到位图数据(bitmap data)开始之间的的偏移量
} BITMAPFILEHEADER ;

紧接着是信息头:

typedef __packed struct
{
    uint32_t biSize ;		   	//说明BITMAPINFOHEADER结构所需要的字数。
    long  biWidth ;		   	//说明图象的宽度,以象素为单位
    long  biHeight ;	   	//说明图象的高度,以象素为单位
    uint16_t  biPlanes ;	   		//为目标设备说明位面数,其值将总是被设为1
    uint16_t  biBitCount ;	   	//说明比特数/象素,其值为1、4、8、16、24、或32
    uint32_t biCompression ;  	//说明图象数据压缩的类型。其值可以是下述值之一:
    //BI_RGB:没有压缩;
    //BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复象素计数和颜色索引);
    //BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成
    //BI_BITFIELDS:每个象素的比特由指定的掩码决定。
    uint32_t biSizeImage ;		//说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0
    long  biXPelsPerMeter ;	//说明水平分辨率,用象素/米表示
    long  biYPelsPerMeter ;	//说明垂直分辨率,用象素/米表示
    uint32_t biClrUsed ;	  	 	//说明位图实际使用的彩色表中的颜色索引数
    uint32_t biClrImportant ; 	//说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BITMAPINFOHEADER ;

然后排序刚才也发现了,是BGR,所以结构体如下:

typedef __packed struct
{
    uint8_t rgbBlue ;    //指定蓝色强度
    uint8_t rgbGreen ;	//指定绿色强度
    uint8_t rgbRed ;	  	//指定红色强度
    uint8_t rgbReserved ;//保留,设置为0
} RGBQUAD ;

位图信息头如果不是888,还需要掩码,我们MCU一般用565也够了,省事.

typedef __packed struct
{
    BITMAPFILEHEADER bmfHeader;
    BITMAPINFOHEADER bmiHeader;
    uint32_t RGB_MASK[3];			//调色板用于存放RGB掩码.
    //RGBQUAD bmiColors[256];
} BITMAPINFO;

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注