bmp文件格式分析
下面来分析bmp文件的格式。
我这里用的是8位256色的灰度图像。其他位深的图像在最后在做介绍。
首先也是点开属性得到下面信息:
图像是20像素宽40像素高的8位灰度图像,大小为1878字节。其中像素占20*40=800byte,文件结构头占1078字节,其实灰度图像的头结构都是占1078字节的。这1078个字节其实又分为两个部分最开头的54个字节是真正的头信息,余下的1024个字节是调色板信息。
先来分析这头54个字节,以ultraedit打开图像得到:
下面的‘这里的值’都是低位在前的。比如 56 07 00 00,实际的应该是00000756H,也就是1878Byte。
起始地址 |
大小 |
这里的值 |
代表的意思 |
00H |
2 |
42 4D |
BM,代表这种文件吧 |
02H |
4 |
56 07 00 00 |
十进制是1878,文件的大小。 |
06H |
2 |
00 00 |
特定应用程序使用,这里不用。 |
08H |
2 |
00 00 |
特定应用程序使用,这里不用。 |
0AH |
4 |
36 04 00 00 |
十进制1078,实际数据开始的偏移地址。 |
0EH |
4 |
28 00 00 00 |
十进制40,从这里开始的图像头信息所占的字节数。 |
12H |
4 |
14 00 00 00 |
十进制20,图像的宽度。 |
16H |
4 |
28 00 00 00 |
十进制40,图像的高度。 |
1AH |
2 |
01 00 |
使用的彩色平面数。都为1。 |
1CH |
2 |
08 00 |
十进制8,图像的位深。 |
1EH |
4 |
00 00 00 00 |
规定像素位的掩码,为8位和32维深的图像时就是一般的RGB,如果是16位图像会有556或565这样的掩码表示。 |
22H |
4 |
20 03 00 00 |
十进制800,这里是实际像素所占的空间。 |
26H |
4 |
00 00 00 00 |
位图水平分辨率,每米像素数。 |
2AH |
4 |
00 00 00 00 |
位图垂直分辨率,每米像素数。 |
2EH |
4 |
00 01 00 00 |
位图中实际使用的颜色表中的颜色数。 |
32H |
4 |
00 00 00 00 |
位图中重要的颜色数。 |
这之后的256*4个字节是调色板的信息,处理图像数据的时候就不用关心这个了,不过不同的调色板信息会对相同的像素产生不同的显示效果。Matlab读取数据时不关心调色板,Opencv读数据会根据调色板信息把实际的像素做变换,所以如果调色板不是00 00 00 00一直到ff ff ff 00这样下来,opencv和matlab读取的像素会有不一致的结果。今天就是有同学来问我这个问题,我才注意到的。调色板只有256色图像之前才有,之后就没有调色板了。也就是说16、24、32位深的图像从上面这个头结构接下来就是图像像素信息了。
现在来说图像的像素信息。bmp中像素的存储和一般的显示效果还是相当迥异的。
下表是24位深像素的存储格式(千万注意,这不是显示格式):
B |
G |
R |
。。。。。
|
B |
G |
R |
很长一段的像素数据。。。。。。。。
|
B |
G |
R |
。。。。。
|
B |
G |
R |
显示的最后一行的最左边的数 |
显示的最后一行的最右边的数 |
显示的第一行的最左边的数 |
显示的第一行的最右边的数 |
最后再说一下黑白图像,黑白图像是位深为1的图像,千万别把256色但只有0和255像素的图像当黑白图像了,我很长一段时间都搞错了。位深为1的图像一个字节能表示8个像素,不过要是像素的行是要4字节对齐的,比如我这里一行20像素,用2字节再加3bit也就是3Byte就可以了,不过还是要扩展到4byte。
由于不可能把各种深度格式都在这里说清楚,所以遇到特殊的情况还需特殊处理。这里就说这些主要的东西吧。
有机会也许会把相关程序附上,也许就是下一篇。
注:相关程序在这里:http://www.cnblogs.com/tiandsp/archive/2012/11/30/2795788.html