BMP图片结构解析

BMP图片结构

bmp图片由文件头,位图信息头,24位图片以下还有调色板,和图像数据组成。
下面先分析一张4位的BMP图片(25*25),用UE打开图片。
在这里插入图片描述

文件头

文件头包括下列项
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;

  • bfType(2byte)
    文件类型,具体值为0x4D42 = “BM”
  • bfSize(4byte)
    文件大小,此图片大小为0x00000206 = 518(十进制)byte。
  • bfReserved1和bfReserved2(每个2byte)
    保留项,必须设置为0。
  • bfOffBits(4byte)
    从文件开头到具体图像数据的字节偏移量,0x00000076 = 118(十进制),具体文件头(14byte)+位图信息头(40byte)+调色板(64byte) = 118byte。

位图信息头

包含下列项
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(4byte)
    位图信息头的大小,所有图片均为0x00000028 = 40(十进制)byte。
  • biWidth(4byte)
    位图宽度,单位为像素,0x00000019 = 25(十进制)。
  • biHeight;(4byte)
    位图高度,单位为像素,0x00000019 = 25(十进制)。
  • biPlanes(2byte)
    位图的平面数,设置为1,0x0001。
  • biBitCount(2byte)
    颜色深度(位数),又称位深度、位分辨率,单位为bpp(bit/像素点),意为存储每个像素点需要的bit数,值有1,4,8,16,24,32等。此图片为0x0004 = 4位。
  • biCompression(4byte)
    是否压缩,0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。0x00000000为不压缩。
  • biSizeImage(4byte)
    图像数据部分大小,单位字节,数值上等于位图宽度大小(单位字节,必须是离宽度字节数最近而且是4的倍数值)×位图高度,上图位图宽度是16byte*25的高度=400byte,下面会详细说明。0x00000190 = 400,图片分析与计算一致。
  • biXPelsPerMeter(4byte)
    用像素/米表示的水平分辨率,0x00001EC2 = 7874(十进制)。
  • biYPelsPerMeter(4byte)
    用像素/米表示的水平分辨率,0x00001EC2 = 7874(十进制)。
  • biClrUsed(4byte)
    调色板中的颜色索引数,0为图片有调色板。
  • biClrImportant(4byte)
    重要影响的颜色索引数,0表示都重要。

调色板

结构为蓝,绿,红的顺序排列,最后一位为保留项。
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
调色板中的数据每4字节一组,分别表示蓝、绿、红和保留值(十六进制),该图片的颜色数为2^4=16种,占用的字节数为16 * 4=64byte。

索引绿保留值
000000000
111111100
222222200
00
14EEEEEE00
15FFFFFF00

而在8位的BMP图片中,图片的颜色就有2^8=256种,占用的字节数为256*4=1024byte。

索引绿保留值
000000000
101010100
202020200
303030300
00
254FEFEFE00
255FFFFFF00

图像数据

有了调色板的索引表,在图像数据里就会用索引值表示像素点。图片的实际宽度大小=位图宽度存储每个像素需要的字节数%4?位图宽度存储每个像素需要的字节数:离(位图宽度*存储每个像素需要的字节数)最近的大于它的值。

4位BMP图片的图像数据:

4位BMP图像数据
每个像素点用4bit表示,FF就表示前两个像素点的颜色均为调色板中索引号为F的颜色(白色);依次往后,FB中,索引号为B的颜色为灰色;00表示两个像素点均为调色板中索引号为0的颜色(黑色)。4位的图片每个像素点需要4/8byte,而图片的宽度为25像素,就需要12.5字节表示,而每行的字节数必须是4的整数倍,离12.5最近的数是16字节,所以每行就需要16字节存储,不足的用其他值补全,而这样的数据一共有25行,所有图像数据大小为16*25=400byte。4位的24×24每行为12byte,33×33为16.5byte,补全为20byte。图像的数据大小根据biSizeImage的值末尾不够的位会用00补全。
每行的字节数除了自己分析之外,也可以直接用下列公式计算:
DataSizePerLine1=biBitCount * biWidth/32 * 4,
实际每个扫描行所占字节数计算方法为:
DataSizePerLine2= (biWidth * biBitCount+31)/ 32 * 4;

8位BMP图片的图像数据:

8位BMP图像数据
每个像素点用8bit表示,FF表示此像素点的颜色为调色板中第255个索引号的颜色(白色)。CE表示像素点为第206个索引号的颜色(灰偏白),03表示像素点为第3个索引号的颜色(基本全黑)。此图片为35×35像素,每个扫描行实际字节数为(35 * 8+31)/32*4 = 36byte, 37×37的实际宽度字节数为40byte。

24位BMP图片的图像数据:

24位真彩色的BMP图片,没有调色板,在文件头和位图信息头后面直接是图像数据。
下图是一张14×14的24位BMP图片。
在这里插入图片描述
图片中没有调色板,宽度为14像素,每个像素点用3byte表示,每行的数据大小为14×3=42byte,不能被4整除,用00补全到44byte,用公式计算((14 * 24+31)/32 * 4 == 44)。三个字节分别表示B,G,R的值,每行末尾用其他值补全,对图像进行处理时,要注意跳过这些无效的填充数据。即:

BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR 00 00
BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR 00 00
… …
BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR BGR 00 00

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值