Bmp 位图显示¶
概览Overview¶
二维数组.整型均以小端存储序存储.
| 偏移字节 | 数据类型 | 大小(字节) | 作用 | 默认值 | 名称(可供参考) |
|---|---|---|---|---|---|
| 1 | 字符型 | 1 | 标识此图为Bmp位图文件 | 0x42('B') | CharB |
| 2 | 字符型 | 1 | 标识此图为Bmp位图文件 | 0x4D('M') | CharM |
| 3 ~ 6 | 32位无符号整型 | 4 | Bmp整个文件的大小(包括Bmp File Header等) | Size | |
| 7 ~ 8 | - | 2 | 保留 | 视具体情况,一般为 0 | Reserved1 |
| 9 ~ 10 | - | 2 | 保留 | 视具体情况,一般为 0 | Reserved2 |
| 11 ~ 14 | 32位无符号整型 | 4 | 记录像素数据相对于整个文件开头的偏移字节 | 视具体情况,24bit位图为54 | ImageOffset |
| 15 ~ 18 | 32位无符号整型 | 4 | Bitmap Info Header 大小(字节) | 40 | HeaderSize |
| 19 ~ 22 | 32位整型 | 4 | 位图宽度(像素),但不可为负(正常情况下大多软件不支持包括ffplay) | 正整数值 | Width |
| 23 ~ 26 | 32位整型 | 4 | 位图高度(像素),如果为负数,具体见下文"像素存储"... | Height | |
| 27 ~ 28 | 16位无符号整型 | 2 | 必须是 1,Wiki上写的是色彩平面数 | 1 | Planes |
| 29 ~ 30 | 16位无符号整型 | 2 | 像素所占位数,也就是图像位深、色深,值可能为1、4、8、24、32.如32bit用4字节存储一个像素 | ImageBits | |
| 31 ~ 34 | 32位无符号整型 | 4 | 压缩方式(本文不展开叙述) | 0 | CompressionType |
| 35 ~ 38 | 32位无符号整型 | 4 | ImageSize | 见下 | ImageSize |
| 39 ~ 42 | 32位无符号整型 | 4 | 横向分辨率(像素/米) | HorizontalResolution | |
| 43 ~ 46 | 32位无符号整型 | 4 | 竖向分辨率(像素/米) | VerticalResolution | |
| 47 ~ 50 | 32位无符号整型 | 4 | 调色板颜色数,等于"2^位深",即2的位深值的次方个, 24Bit以上由于直接存储BGR(或BGRA)值,调色板个数为0 | \(2^{位深}\) | PaletteColorsNum |
| 51 ~ 54 | 32位无符号整型 | 4 | 重要颜色数,为0则是全部颜色都很重要 | 0 | ImportantColorsNum |
细节¶
偏移ImageOffset¶
Bmp像素数据起始位置相对于文件起始处的偏移.一般的:
\(ImageOffset=54+4\times PaletteColorsNum\)
假若bedrodk.bmp在内存中文件起始位置为BmpRaw,则像素数据起始位置为PixelStart = BmpRaw + ImageOffset
位深ImageBits¶
Bmp位深多少,即用多少各Bit存储一个像素.
如1Bit使用0.125个字节存储一个像素,其余的按四字节对齐(不足的按四字节算).
在一定范围内,位深越大,带给人的感受越真实.
32Bit的Bmp位图,使用BGRA即[Blue,Green,Red,Alpha]进行对像素的存储,比24Bit位图的BGR多了一条Alpha通道.
调色板BmpColorMap¶
每个调色板占用4个字节,存储格式为BGRR,即[Bule,Green,Red,Reserved],每个值都是8Bit无符号整型(即unsigned char).下面C/C++的定义应该更加直观.
相当于一个索引,打个比方:
在一张8Bit的Bmp位图中,使用8个Bit即1字节存储一个像素.那么一个像素需要一个字节存储,则一个字节可存储0 ~ 255的无符号整型数据.如果有一个字节存储的值是255,则对应的第255个调色板BGRR值为 [0xFF 0xFF 0xFF 0x00].
一般情况下,需要"翻译"成24Bit或32Bit.具体见下文.
一张24Bit或32Bit的Bmp位图不存在调色板,因为它们直接存储像素的具体BGR或BGRA值,则\(PaletteColorsNum = 0\)
文件大小Size¶
\(Size = 54 + ImageSize + PaletteColorsNum \times 4\)
其中,4指的是每个调色板占用的字节数,54指的是Bmp文件头和位图头的总大小.
调色板个数PaletteColorsNum¶
在ImageBits不为24或32的情况下(具体见上文-调色板BmpColorMap):
\(PaletteColorsNum = 2^{ImageBits}\)
为24或32时:
\(PaletteColorsNum = 0\)
对齐后像素数据大小ImageSize¶
用数学公式说有点迷糊(我也还没学MOD)
要对齐时:
$RowSize=\frac {Width\times ImageBits} {8} +4 - (\frac {Width\times ImageBits} {8} \mod 4) $
不用对齐时:
\(RowSize = \frac {Width\times ImageBits} {8}\)
对于所有情况,都有:
\(ImageSize=Height\times RowSize\)
RowSize即储存一行的像素数据所需要的字节数.
ImageSIze代表一张Bmp图像储存像素区域所占的字节数.
要对齐时的情况推导:
Bmp图像在储存数据时,记录范围内的每个像素(或调色板信息),会进行四字节对齐(不满四字节按四字节算).
则储存一行时不对齐情况下的字节数是:\(\frac {ImageBits} 8\times Width\)
不考虑多出字节进行4字节对齐时,多出字节数为:\((\frac {ImageBits} 8\times Width) \mod 4\)
则考虑多出字节进行4字节对齐时,需补齐字节数为:\(4-[(\frac {ImageBits} 8\times Width) \mod 4]\)
则一行占用:$RowSize=\frac {Width\times ImageBits} {8} +4 - (\frac {Width\times ImageBits} {8} \mod 4) $
再回去想想就行了...(指去上文QwQ)
宽度Width & 高度Height¶
Width不可为负数.
Height可为负数.影响见下文.
像素存储¶
正常情况下,Bmp会形成一个\(Width \times Height\)大小的数组,这里称BmpRaw,存在对齐情况,实际描述为二维数组,但在存储或读取时大多使用线型.
Height为正数时,实际平面内最左上角的数据起始位置在BmpRaw的最后行的第一列,即BmpRaw[(Height - 1)*Width + 1],为负数则在BmpRaw的第一行的第一列,即BmpRaw[0].
Files¶
Src/Resources/*.bmpSrc/Include/Boot/Bmp.hSrc/SigmaBootPkg/Bmp.c