下面來分析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