BMP图片内部结构

BMP图片内部结构

​ BMP文件的数据按照从文件头开始的先后顺序分为四个部分:分别是位图文件头、位图信息头、调色板(24bit位图是没有的)、位图数据(RGB)。

(1)位图文件头(Bitmap-File Header)包含了图像类型、图像大小、两个保留字以及位图数据存放地址。

image

(2)位图信息头(Bitmap-Information Header)包含了位图信息头的大小、图像的宽和高、图像的色深、压缩说明、图像数据的大小和其他一些参数。

image

(3)调色板是为了让一些颜色深度比较小(1bit、4bit、8bit)的位图可以表示颜色而设置的。调色板存储颜色,后面的位图数据存储颜色索引,这样调色板+位图数据就可以表示颜色了。

16bit、24bit、32bit的位图一般没有调色板,因为从16bit开始就直接使用位图数据表示颜色了。

(4)位图数据分两种情况,如果带调色板,则位图数据存放的是调色板的颜色索引,如果不带调色板,则位图数据存放实际的argb值。由于24位bmp图片不带调色板,所以文件开头的54字节为图片信息,从第55个字节开始就为bmp图片的颜色数据。

当需要读取图像文件信息时,可以从图像文件的相应位置进行数据提取,这是可以定义位图文件头和信息头的结构体,如下:

//取消字节对齐,因为需要的结构体是 14字节和 40字节大小
#pragma pack(1)
//定义图像文件头结构体
typedef struct BMP_FileHeader
{
    unsigned char      bfType[2];          //位图文件的类型,必须为BM 
    unsigned int        bfSize;            //文件大小,以字节为单位
    unsigned short int  bfReserverd1;      //位图文件保留字,必须为0 
    unsigned short int  bfReserverd2;      //位图文件保留字,必须为0 
    unsigned int        bfbfOffBits;       //位图文件头到数据的偏移量,以字节为单位
}BMP_FInfo_t;
//定义图像信息头结构体
typedef  struct BMP_InfoHeader
{ 
    unsigned int biSize;                       //该结构大小,字节为单位
    unsigned int  biWidth;                     //图形宽度以象素为单位
    unsigned int  biHeight;                    //图形高度以象素为单位
    unsigned short int  biPlanes;              //目标设备的级别,必须为1 
    unsigned short int  biBitcount;            //颜色深度,每个象素所需要的位数
    unsigned short int  biCompression;         //位图的压缩类型
    unsigned int  biSizeImage;                 //位图的大小,以字节为单位
    unsigned int  biXPelsPermeter;             //位图水平分辨率,每米像素数
    unsigned int  biYPelsPermeter;             //位图垂直分辨率,每米像素数
    unsigned int  biClrUsed;                   //位图实际使用的颜色表中的颜色数
    unsigned int  biClrImportant;              //位图显示过程中重要的颜色数
}BMP_InfoHeader_t;

#pragma pack()      //开启字节对齐

其中需要注意的是,CPU为了提高数据读取效率,会对结构体的变量进行字节对齐,也就是在32位系统下,结构体变量的字节宽度会自动补齐为 4 的倍数。而位图文件头是 14字节大小,并不是 4的尾数,所以我们需要取消字节对齐,用预处理指令 #pragma pack(n),n为字节对齐数,当 n = 1 时,表示CPU 最小以一个字节读取数据,同理,位图信息头是 40个字节大小,也需要取消字节对齐,当定义结束之后,要恢复字节对齐,直接写 #pragma pack(),n不写时,默认是CPU 本身的对齐字节数。

posted @ 2024-05-11 19:58  沉舟道人  阅读(100)  评论(0编辑  收藏  举报