1、显示数据的存储格式
先不考虑BMP文件的文件头部分,显示数据的存储格式如下图所示:
由上图可见,BMP文件中的显示数据是以行为单位倒序存储的,就是说图片第一行的显示数据存储在文件数据的最后面一行,
图片最后一行的显示数据则保存在文件数据的第一行。
2、BMP图片的文件头
BMP图片的文件头可以用如下两个结构体来表示,两个结构体占用的空间共为54字节。
//14byte文件头
typedef struct
{
char cfType[2]; //文件类型,"BM"(0x4D42)
long cfSize; //文件大小(字节)
long cfReserved;//保留,值为0
long cfoffBits; //数据区相对于文件头的偏移量(字节)
}__attribute__((packed)) BITMAPFILEHEADER;//__attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐
//40byte信息头
typedef struct
{
char ciSize[4]; //BITMAPFILEHEADER所占的字节数
long ciWidth; //宽度
long ciHeight; //高度
char ciPlanes[2]; //目标设备的位平面数,值为1
int ciBitCount; //每个像素的位数
char ciCompress[4]; //压缩说明
char ciSizeImage[4];//用字节表示的图像大小,该数据必须是4的倍数
char ciXPelsPerMeter[4];//目标设备的水平像素数/米
char ciYPelsPerMeter[4];//目标设备的垂直像素数/米
char ciClrUsed[4]; //位图使用调色板的颜色数
char ciClrImportant[4]; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
}__attribute__((packed)) BITMAPINFOHEADER;
3、显示数据的对齐问题
BMP图片内的显示数据,按行进行4字节对齐,也就是说每一行显示数据所占据的存储空间必须是4字节的整数倍,不足的部分要补零。
然后才是下一行的显示数据。对于深度为24bit的图片,每一行所占据的空间大小可以通过如下方式计算:
size = (width * 3 + 3) / 4 * 4;
4、RGB888格式的BMP图片显示数据转换为可以直接显示的RGB8888数据
int cursor_bitmap_format_convert(char *dst,char *src,unsigned int offset)
{
int i ,j ;
char *psrc = src ;
char *pdst = dst;
char *p = psrc;
/*
由于BMP显示数据是按行从后面往前面存储,
所以需要倒序进行转换。
*/
for(i = height;i > 0; i--){
p = psrc + (i-1) * offset;
for(j = 0;j < width; j++){
*pdst++ = *p++;
*pdst++ = *p++;
*pdst++ = *p++;
*pdst++ = 0x00;
}
}
return 0;
}