BMP图像数据格式详解
https://www.cnblogs.com/l2rf/p/5643352.html
一.简介
BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
二.BMP格式结构
BMP文件的数据按照从文件头开始的先后顺序分为四个部分:
◆ 位图文件头(bmp file header): 提供文件的格式、大小等信息
◆ 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
◆ 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
◆ 位图数据(bitmap data):图像数据区
BMP图片文件数据表如下:
数据段名称
|
大小(byte)
|
开始地址
|
结束地址
|
位图文件头(bitmap-file header)
|
14
|
0000h
|
000Dh
|
位图信息头(bitmap-information header)
|
40
|
000Eh
|
0035h
|
调色板(color table)
|
由biBitCount决定
|
0036h
|
未知
|
图片点阵数据(bitmap data)
|
由图片大小和颜色定
|
未知
|
未知
|
三.BMP文件头
BMP文件头结构体定义如下:
typedef struct tagBITMAPFILEHEADER
{
UINT16 bfType; //2Bytes,必须为"BM",即0x424D 才是Windows位图文件
DWORD bfSize; //4Bytes,整个BMP文件的大小
UINT16 bfReserved1; //2Bytes,保留,为0
UINT16 bfReserved2; //2Bytes,保留,为0
DWORD bfOffBits; //4Bytes,文件起始位置到图像像素数据的字节偏移量
} BITMAPFILEHEADER;
BMP文件头数据表如下:
变量名
|
地址偏移
|
大小
|
作用说明
|
bfType
|
0000h
|
2Bytes
|
文件标识符,必须为"BM",即0x424D 才是Windows位图文件
‘BM’:Windows 3.1x, 95, NT,… ‘BA’:OS/2 Bitmap Array ‘CI’:OS/2 Color Icon
‘CP’:OS/2 Color Pointer ‘IC’:OS/2 Icon
‘PT’:OS/2 Pointer
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行
|
bfSize
|
0002h
|
4Bytes
|
整个BMP文件的大小(以位B为单位)
|
bfReserved1
|
0006h
|
2Bytes
|
保留,必须设置为0
|
bfReserved2
|
0008h
|
2Bytes
|
保留,必须设置为0
|
bfOffBits
|
000Ah
|
4Bytes
|
说明从文件头0000h开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据
|
四.BMP信息头
BMP信息头结构体定义如下:
typedef struct _tagBMP_INFOHEADER
{
DWORD biSize; //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
LONG biWidth; //4Bytes,图像宽度(以像素为单位)
LONG biHeight; //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
WORD biPlanes; //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
WORD biBitCount; //2Bytes,图像像素位数
DWORD biCompression; //4Bytes,0:不压缩,1:RLE8,2:RLE4
DWORD biSizeImage; //4Bytes,4字节对齐的图像数据大小
LONG biXPelsPerMeter; //4 Bytes,用象素/米表示的水平分辨率
LONG biYPelsPerMeter; //4 Bytes,用象素/米表示的垂直分辨率
DWORD biClrUsed; //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
DWORD biClrImportant; //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
}BMP_INFOHEADER;
BMP信息头数据表如下:
变量名
|
地址偏移
|
大小
|
作用说明
|
biSize
|
000Eh
|
4Bytes
|
BNP信息头即BMP_INFOHEADER结构体所需要的字节数(以字节为单位)
|
biWidth
|
0012h
|
4Bytes
|
说明图像的宽度(以像素为单位)
|
biHeight
|
0016h
|
4Bytes
|
说明图像的高度(以像素为单位)。这个值还有一个用处,指明图像是正向的位图还是倒向的位图,该值是正数说明图像是倒向的即图像存储是由下到上;该值是负数说明图像是倒向的即图像存储是由上到下。大多数BMP位图是倒向的位图,所以此值是正值。
|
biPlanes
|
001Ah
|
2Bytes
|
为目标设备说明位面数,其值总设置为1
|
biBitCount
|
001Ch
|
2Bytes
|
说明一个像素点占几位(以比特位/像素位单位),其值可为1,4,8,16,24或32
|
biCompression
|
001Eh
|
4Bytes
|
说明图像数据的压缩类型,取值范围为:
0 BI_RGB 不压缩(最常用)
1 BI_RLE8 8比特游程编码(BLE),只用于8位位图
2 BI_RLE4 4比特游程编码(BLE),只用于4位位图
3 BI_BITFIELDS比特域(BLE),只用于16/32位位图
4
|
biSizeImage
|
0022h
|
4Bytes
|
说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0
|
biXPelsPerMeter
|
0026h
|
4Bytes
|
说明水平分辨率,用像素/米表示,有符号整数
|
biYPelsPerMeter
|
002Ah
|
4Bytes
|
说明垂直分辨率,用像素/米表示,有符号整数
|
biClrUsed
|
002Eh
|
4Bytes
|
说明位图实际使用的调色板索引数,0:使用所有的调色板索引
|
biClrImportant
|
0032h
|
4Bytes
|
说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。
|
五.BMP调色板
BMP调色板结构体定义如下:
typedef struct _tagRGBQUAD
{
BYTE rgbBlue; //指定蓝色强度
BYTE rgbGreen; //指定绿色强度
BYTE rgbRed; //指定红色强度
BYTE rgbReserved; //保留,设置为0
} RGBQUAD;
1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。
颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图的透明度值,一般不需要)。即首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。
颜色表中RGBQUAD结构数据的个数有biBitCount来确定,当biBitCount=1,4,8时,分别有2,16,256个表项。
当biBitCount=1时,为2色图像,BMP位图中有2个数据结构RGBQUAD,一个调色板占用4字节数据,所以2色图像的调色板长度为2*4为8字节。
当biBitCount=4时,为16色图像,BMP位图中有16个数据结构RGBQUAD,一个调色板占用4字节数据,所以16像的调色板长度为16*4为64字节。
当biBitCount=8时,为256色图像,BMP位图中有256个数据结构RGBQUAD,一个调色板占用4字节数据,所以256色图像的调色板长度为256*4为1024字节。
当biBitCount=16,24或32时,没有颜色表。
五.BMP图像数据区
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,
一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine* biHeight;
颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。
_________________________________________________________________________________________________________________________________________________
每一个不曾起舞的日子,都是对生命的辜负。
But it is the same with man as with the tree. The more he seeks to rise into the height and light, the more vigorously do his roots struggle earthward, downward, into the dark, the deep - into evil.
其实人跟树是一样的,越是向往高处的阳光,它的根就越要伸向黑暗的地底。----尼采
每一个不曾起舞的日子,都是对生命的辜负。
But it is the same with man as with the tree. The more he seeks to rise into the height and light, the more vigorously do his roots struggle earthward, downward, into the dark, the deep - into evil.
其实人跟树是一样的,越是向往高处的阳光,它的根就越要伸向黑暗的地底。----尼采
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话