数字图像处理之位图在计算机中的存储结构
位圖是windows中廣泛應(yīng)用的一種圖像格式,其后綴名為.bmp.位圖也稱為位映射圖片.一張位圖包含了
許許多多的像素點(diǎn),每個(gè)像素點(diǎn)有不同的顏色。由此構(gòu)成了五彩斑斕的位圖圖像,然而正是因?yàn)橛上袼攸c(diǎn)
這一基本元素構(gòu)成,所以在放大圖片的時(shí)候,人眼便能夠區(qū)分一個(gè)一個(gè)的像素點(diǎn),進(jìn)而造成位圖失真。本
文主要介紹位圖文件在計(jì)算機(jī)內(nèi)存中的存儲(chǔ)形式。
當(dāng)然這里還要介紹兩種位圖:DDB,DIB
DDB(device dependent bitmap),為設(shè)備相關(guān)位圖,這種位圖與具體的輸出設(shè)備相關(guān)。在這種位圖的結(jié)構(gòu)中
沒有保存調(diào)色板信息。因?yàn)樵谳敵鲲@示時(shí)是調(diào)用系統(tǒng)的調(diào)色板。這便是這種位圖的局限性。
DIB(device independent bitmap),為設(shè)備無關(guān)位圖。這種位圖與具體的輸出無關(guān)。其結(jié)構(gòu)中包含四個(gè)部分文件
頭,信息頭,調(diào)色板,數(shù)據(jù)區(qū)域。所以下文均是介紹這種位圖的結(jié)構(gòu)信息。
BMP文件由文件頭,位圖信息頭,顏色信息和圖像數(shù)據(jù)四部分組成。
這wingdi.h中對(duì)位圖文件頭和信息頭也作了相應(yīng)的結(jié)構(gòu)體定義。
1 //對(duì)位圖文件頭的定義
2
3 typedef struct tagBITMAPFILEHEADER {
4 WORD bfType; //位圖文件的類型, 必須為BM 對(duì)應(yīng)的16進(jìn)制為0x4D42
5 DWORD bfSize; //位圖文件的大小,字節(jié)單位
6 WORD bfReserved1; //位圖文件保留字,必須為0
7 WORD bfReserved2; //位圖文件保留字,必須為0
8 DWORD bfOffBits; //為從文件頭到實(shí)際圖像數(shù)據(jù)區(qū)域的長度,即前三個(gè)結(jié)構(gòu)長度之和。
9 } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
文件頭長度固定為14個(gè)字節(jié),其中WORD占兩個(gè)字節(jié),DWORD占四個(gè)字節(jié)。
1 //對(duì)位圖信息頭的定義
2
3 typedef struct tagBITMAPINFOHEADER{
4 DWORD biSize; //指定該信息頭所占字節(jié)數(shù),固定占40個(gè)字節(jié)
5 LONG biWidth; //位圖的寬度,單位為像素
6 LONG biHeight; //位圖的高度,單位為像素
7 WORD biPlanes; //目標(biāo)設(shè)備的位面數(shù),必須是1
8 WORD biBitCount; //每個(gè)像素所占的位數(shù)
9 DWORD biCompression; //位圖的壓縮方式,大多數(shù)情況下為0,也可能是BI_RGB
10 DWORD biSizeImage; //位圖的大小,字節(jié)單位
11 LONG biXPelsPerMeter; //水平分辨率,水平每米所占像素個(gè)數(shù)
12 LONG biYPelsPerMeter; //垂直分辨率,垂直每米所占像素個(gè)數(shù)
13 DWORD biClrUsed; //指出該位圖中實(shí)際使用的色彩數(shù),若為0,則為2^biBitCount
14 DWORD biClrImportant; //位圖顯示中比較重要的顏色數(shù),若為0,則所有顏色都是重要的。
15 } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
信息頭固定長度為40個(gè)字節(jié),其中word占兩個(gè)字節(jié),Dword和Long各占四個(gè)字節(jié)。
1 //對(duì)顏色表的定義(針對(duì)一個(gè)像素而定義)
2
3 typedef struct tagRGBQUAD {
4 BYTE rgbBlue; //該顏色的藍(lán)色分量(0-255)
5 BYTE rgbGreen; //該顏色的綠色分量(0-255)
6 BYTE rgbRed; //該顏色的紅色分量(0-255)
7 BYTE rgbReserved; //保留值
8 } RGBQUAD;
顏色表中RGBQUAD結(jié)構(gòu)數(shù)據(jù)的個(gè)數(shù)有biBitCount來確定:
當(dāng)biBitCount=1,4,8時(shí),分別有2,16,256個(gè)表項(xiàng);
當(dāng)biBitCount=24時(shí),沒有顏色表項(xiàng)。
位圖信息頭和顏色表組成位圖信息,BITMAPINFO結(jié)構(gòu)定義如下:
1 typedef struct tagBITMAPINFO
2 {
3 BITMAPINFOHEADER bmiHeader; // 位圖信息頭
4 RGBQUAD bmiColors[1]; // 顏色表
5 } BITMAPINFO;
//位圖數(shù)據(jù)
位圖數(shù)據(jù)記錄了位圖的每一個(gè)像素值,記錄順序是在掃描行內(nèi)是從左到右,掃描行之間是從下到上。
位圖的一個(gè)像素值所占的字節(jié)數(shù):
當(dāng)biBitCount=1時(shí),8個(gè)像素占1個(gè)字節(jié);
當(dāng)biBitCount=4時(shí),2個(gè)像素占1個(gè)字節(jié);
當(dāng)biBitCount=8時(shí),1個(gè)像素占1個(gè)字節(jié);
當(dāng)biBitCount=24時(shí),1個(gè)像素占3個(gè)字節(jié);
Windows規(guī)定一個(gè)掃描行所占的字節(jié)數(shù)必須是
4的倍數(shù)(即以long為單位),不足的以0填充,
一個(gè)掃描行所占的字節(jié)數(shù)計(jì)算方法:
DataSizePerLine=(biWidth*biBitCount+31)/8;
//一個(gè)掃描行所占的字節(jié)數(shù)
DataSizePerLine=DataSizePerLine/4*4;//
字節(jié)數(shù)必須是4的倍數(shù)
位圖數(shù)據(jù)的大小(不壓縮情況下):
DataSize=DataSizePerLine*biHeight;
下面用hexeditor16位編輯器對(duì)一張位圖的存儲(chǔ)結(jié)構(gòu)進(jìn)行說明:
上圖則是對(duì)蘋果位圖用16位編輯器打開后的存儲(chǔ)結(jié)構(gòu)
前14個(gè)字節(jié)為位圖文件頭:
0-1字節(jié):42 4D 位圖類型BM
2-5字節(jié):36 A8 05 00 位圖文件大小為實(shí)際上應(yīng)該0x0005A836 總共為370742個(gè)字節(jié)
6-7字節(jié):00 00 保留字 0
8-9字節(jié):00 00保留字 0
10-13字節(jié):36 00 00 00位圖文件頭到數(shù)據(jù)的偏移,實(shí)際上為00 00 00 36,實(shí)例偏移為54字節(jié)。
而文件頭14字節(jié),信息頭40字節(jié)一共54字節(jié)。那么顏色表呢?顏色表為0.是的,顏色表為0
說明該位圖使用24位真彩色,而非索引調(diào)色板。故位圖信息結(jié)構(gòu)中不包括調(diào)色板。
第14到53這40個(gè)字節(jié)為位圖信息頭:
14-17字節(jié):28 00 00 00實(shí)際上為0x00000028=40標(biāo)識(shí)該信息頭結(jié)構(gòu)所占字節(jié)數(shù)。
18-21字節(jié):55 01 00 00實(shí)際上為0x00000155=341標(biāo)識(shí)該位圖的寬度,單位為像素
22-25字節(jié):00 00 01 6A實(shí)際上為0x0000016A=362標(biāo)識(shí)該位圖的高度,單位為像素
26-27字節(jié):01 00實(shí)際上為0x0001=1標(biāo)識(shí)目標(biāo)設(shè)備的位面數(shù),強(qiáng)制為1
28-29字節(jié):18 00實(shí)際上為0x0018=24標(biāo)識(shí)每個(gè)像素所占的位數(shù)。因?yàn)槊總€(gè)像素由RGB三種
顏色分量組成,且每個(gè)分量占一個(gè)字節(jié)。而每個(gè)像素占24.故該圖使用了RGB三種
分量的所有組合,為24色真彩色圖像
30-33字節(jié):00 00 00 00實(shí)際上為0,標(biāo)識(shí)位圖壓縮類型
34-37字節(jié):00 A8 05 00實(shí)際上為0x0005A800=1448,表示為位圖大小,字節(jié)為單位
38-41字節(jié):C4 0E 00 00實(shí)際上為0x00000EC4=3780,表示水平每米所占的像素,即水平分辨率
42-45字節(jié):C4 0E 00 00實(shí)際上為0x00000EC4=3780,表示垂直每米所占的像素,即垂直分辨率
46-49字節(jié):00 00 00 00表示實(shí)際使用的顏色數(shù)。若為0,則標(biāo)識(shí)為真彩色位圖,使用的顏色種類為2^biBitCount
50-53字節(jié):00 00 00 00表示位圖顯示中比較重要的顏色數(shù).若為0,則標(biāo)識(shí)位圖中所以的顏色都重要
而位圖圖像數(shù)據(jù)的掃描讀取方式則是以從左到右,從下到上的方式進(jìn)行。而本圖又為24位真彩圖,故每個(gè)像素
占三個(gè)字節(jié)。故每次從最后一行開始從左到右。一次性讀三個(gè)字節(jié)代表一個(gè)像素的顏色數(shù)據(jù)值。
而對(duì)應(yīng)非24為真色圖:
當(dāng)biBitCount=16時(shí),兩個(gè)字節(jié)代表一個(gè)像素點(diǎn)的顏色數(shù)據(jù)值。此時(shí)存在顏色表,顏色表的種類為2^16種。所以
在圖像中保存此調(diào)色板,在顯示位圖時(shí)調(diào)用此調(diào)色板的索引值以兩個(gè)字節(jié)代表一個(gè)像素點(diǎn)進(jìn)行顯示。
當(dāng)biBitCount=8時(shí),一個(gè)字節(jié)代表一個(gè)像素點(diǎn)的顏色數(shù)據(jù)值。此時(shí)存在顏色表,顏色表的種類為2^8=256種。所
以在圖像中保存此調(diào)色板,在顯示位圖時(shí)調(diào)用此調(diào)色板的索引值以一個(gè)字節(jié)代表一個(gè)像素點(diǎn)進(jìn)行顯示。
當(dāng)biBitCount=4時(shí),半個(gè)字節(jié)代表一個(gè)像素點(diǎn)的顏色數(shù)據(jù)值。此時(shí)存在顏色表,顏色表的種類為2^4=128種。所
以在圖像中保存此調(diào)色板,在顯示位圖時(shí)調(diào)用此調(diào)色板的索引值以半個(gè)字節(jié)代表一個(gè)像素點(diǎn)進(jìn)行顯示,即一個(gè)字
節(jié)表示兩個(gè)像素點(diǎn)。
當(dāng)biBitCount=2時(shí),個(gè)字節(jié)代表一個(gè)像素點(diǎn)的顏色數(shù)據(jù)值。此時(shí)存在顏色表,顏色表的種類為2^2=4種。所以在
圖像中保存此調(diào)色板,在顯示位圖時(shí)調(diào)用此調(diào)色板的索引值以四分之一個(gè)字節(jié)代表一個(gè)像素點(diǎn)進(jìn)行顯示,即
一個(gè)字節(jié)表示四分之一個(gè)像素點(diǎn)。
當(dāng)biBitCount=1時(shí),此時(shí)為灰度圖像。僅黑白兩種顏色。一個(gè)字節(jié)可標(biāo)識(shí)八個(gè)像素點(diǎn)。
所以不能看出顏色深度越神,所保存的調(diào)色板越大,存儲(chǔ)需要的內(nèi)存空間越大。
至此,本文關(guān)于設(shè)備無關(guān)位圖的結(jié)構(gòu)已經(jīng)作了詳解的解釋,相信讀者在看完此文后對(duì)位圖結(jié)構(gòu)有個(gè)大致了解,
以至于在后續(xù)圖像處理的應(yīng)用中有所幫助。
作者水平有限,難免有錯(cuò)誤或者不清除的地方,希望讀者批評(píng)指正大家共同進(jìn)步。
作者:vpoet
出處:http://www.cnblogs.com/vpoet/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
總結(jié)
以上是生活随笔為你收集整理的数字图像处理之位图在计算机中的存储结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: flask url_for()和red
- 下一篇: 企业服务总线(ESB)