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