複製鏈接
請複製以下鏈接發送給好友

dib

鎖定
DIB設備無關位圖文件,這是一種文件格式,是為了保證由某個應用程序創建的位圖圖形可以被其它應用程序裝載或顯示。 DIB的與設備無關性主要體現在以下兩個方面:DIB的顏色模式與設備無關。例如,一個256色的DIB既可以在真彩色顯示模式下使用,也可以在16色模式下使用。256色以下(包括256色)的DIB擁有自己的顏色表,像素的顏色獨立於系統調色板。由於DIB不依賴於具體設備,因此可以用來永久性地保存圖象。DIB一般是以*.BMP文件的形式保存在磁盤中的,有時也會保存在*.DIB文件中。運行在不同輸出設備下的應用程序可以通過DIB來交換圖象。
中文名
dib
簡    介
DIB設備無關位圖文件
類    型
一種文件格式
平    台
windows

dib結構

Borland C++下的框架類庫OWL不同,MFC未提供現成的類來封裝DIB。儘管Microsoft列出了一些理由,但沒有DIB類確實給MFC用户帶來很多不便。用户要想使用DIB,首先應該瞭解DIB的結構。
在內存中,一個完整的DIB由兩部分組成:一個BITMAPINFO結構和一個存儲像素陣列的數組。BITMAPINFO描述了位圖的大小,顏色模式和調色板等各種屬性,其定義為
typedef struct tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1]; //顏色表
}BITMAPINFO;
RGBQUAD結構用來描述顏色,其定義為
typedef struct tagRGBQUAD{
BYTE rgbBlue; //藍色的強度
BYTE rgbGreen; //綠色的強度
BYTE rgbRed; //紅色的強度
BYTE rgbReserved; //保留字節,為0
} RGBQUAD;
注意,RGBQUAD結構中的顏色順序是BGR,而不是平常的RGB
BITMAPINFOHEADER結構包含了DIB的各種信息,其定義為
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //該結構的大小
LONG biWidth; //位圖的寬度(以像素為單位)
LONG biHeight; //位圖的高度(以像素為單位)
WORD biPlanes; //必須為1
WORD biBitCount //每個像素的位數(1、4、8、16、24或32)
DWORD biCompression; //壓縮方式,一般為0或BI_RGB (未壓縮)
DWORD biSizeImage; //以字節為單位的圖象大小(僅用於壓縮位圖)
LONG biXPelsPerMeter; //以目標設備每米的像素數來説明位圖的水平分辨率
LONG biYPelsPerMeter; //以目標設備每米的像素數來説明位圖的垂直分辨率
DWORD biClrUsed; /*顏色表的顏色數,若為0則位圖使用由biBitCount指定的最大顏色數*/
DWORD biClrImportant; //重要顏色的數目,若該值為0則所有顏色都重要
} BITMAPINFOHEADER;
DDB不同,DIB的字節數組是從圖象的最下面一行開始的逐行向上存儲的,也即等於把圖象倒過來然後在逐行掃描。另外,字節數組中每個掃描行的字節數必需是4的倍數,如果不足要用0補齊

dib定義

DIB可以存儲在*.BMP或*.DIB文件中。DIB文件是以BITMAPFILEHEADER結構開頭的 typedef struct tagBITMAPFILEHEADER {
WORD bfType; //文件類型,必須為"BM"
DWORD bfSize; //文件的大小
WORD bfReserved1; //為0
WORD bfReserved2; //為0
DWORD bfOffBits; //存儲的像素陣列相對於文件頭偏移量
} BITMAPFILEHEADER;
緊隨該結構的是一個BITMAPINFOHEADER結構,然後是RGBQUAD結構組成的顏色表(如果有的話),文件最後存儲的是DIB的像素陣列。
DIB的顏色信息儲存在自己的顏色表中,程序一般要根據顏色表為DIB創建邏輯調色板。在輸出一幅DIB之前,程序應該將其邏輯調色板選入到相關的設備上下文中並實現到系統調色板中,然後再調用相關的GDI函數(如::SetDIBitsToDevice或::StretchDIBits)輸出DIB。在輸出過程中,GDI函數會把DIB轉換成DDB,這項工作主要包括以下兩步:
將DIB的顏色格式轉換成與輸出設備相同的顏色格式。例如,在真彩色的顯示模式下要顯示一個256色的DIB,則應該將其轉換成24位的顏色格式。
將DIB像素的邏輯顏色索引轉換成系統調色板索引。

dib編寫類

由於MFC未提供DIB類,用户在使用DIB時將面臨繁重的Windows API編程任務。幸運的是,Visual C++提供了一個較高層次的API,簡化了DIB的使用。這些API函數實際上是由MFC的DibLook例程提供的,它們位於DibLook目錄下的dibapi.cpp、myfile.cpp和dibapi.h文件中,主要包括:
ReadDIBFile //把DIB文件讀入內存
SaveDIB //把DIB保存到文件中
CreateDIBPalette //從DIB中創建一個邏輯調色板
PaintDIB //顯示DIB
DIBWidth //返回DIB的寬度
DIBHeight //返回DIB的高度
DIB區塊
DIB能擁有幾種色彩組織中的一種,DDB必須是單色的或是與真實輸出設備相同的格式。DIB是一個文件或內存塊;DDB是GDI點陣圖物件並由點陣圖代號表示。DIB能被顯示或轉換為DDB並轉換回DIB,但是這裏包含了設備無關位圖和設備相關位圖之間的轉換程序。
您將遇到一個函數,它打破了這些規則。該函數在32位元Windows版本中發表,稱為CreateDIBSection,語法為:
hBitmap = CreateDIBSection (
hdc, // device context handle
pInfo, // pointer to DIB information
fClrUse, // color use flag
ppBits, // pointer to pointer variable
hSection, // file-mapping object handle
dwOffset) ; // offset to bits in file-mapping object
CreateDIBSection是Windows API中最重要的函式之一(至少在使用點陣圖時),然而您會發現它很深奧並難以理解。

dib基本介紹

讓我們從它的名稱開始,我們知道DIB是什麼,但「DIB section」到底是什麼呢?當您第一次檢查CreateDIBSection時,可能會尋找該函式與DIB區塊工作的方式。這是正確的,CreateDIBSection所做的就是建立了DIB的一部分(點陣圖圖素位元的記憶體塊)。
我們看一下傳回值,它是GDI點陣圖物件的代號,這個傳回值可能是該函式呼叫最會拐人的部分。傳回值似乎暗示著CreateDIBSection在功能上與CreateDIBitmap相同。事實上,它只是相似但完全不同。實際上,從CreateDIBSection傳回的點陣圖代號與我們在本章和上一章遇到的所有點陣圖建立函式傳回的點陣圖代號在本質上不同。
一旦理解了CreateDIBSection的真實特性,您可能覺得奇怪為什麼不把傳回值定義得有所區別。您也可能得出結論:CreateDIBSection應該稱之為CreateDIBitmap,並且如同我前面所指出的CreateDIBitmap應該稱之為CreateDDBitmap。

dib使用

首先讓我們檢查一下如何簡化CreateDIBSection,並正確地使用它。首先,把最後兩個參數hSection和dwOffset,分別設定為NULL和0。第二,僅在fColorUse參數設定為DIB_ PAL_COLORS時,才使用hdc參數,如果fColorUse為DIB_RGB_COLORS(或0),hdc將被忽略(這與CreateDIBitmap不同,hdc參數用於取得與DDB相容的設備的色彩格式)。
因此,CreateDIBSection最簡單的形式僅需要第二和第四個參數。第二個參數是指向BITMAPINFO結構的指針,我們以前曾使用過。我希望指向第四個參數的指標定義的指標不會使您困惑,它實際上很簡單。
假設要建立每圖素24位元的384×256位元DIB,24位元格式不需要色彩對照表,因此它是最簡單的,所以我們可以為BITMAPINFO參數使用BITMAPINFOHEADER結構。
您需要定義三個變數:BITMAPINFOHEADER結構、BYTE指標和點陣圖代號:
BITMAPINFOHEADER bmih ;
BYTE * pBits ;
HBITMAP hBitmap ;
初始化BITMAPINFOHEADER結構的欄位
bmih->biSize = sizeof (BITMAPINFOHEADER) ;
bmih->biWidth = 384 ;
bmih->biHeight = 256 ;
bmih->biPlanes = 1 ;
bmih->biBitCount = 24 ;
bmih->biCompression = BI_RGB ;
bmih->biSizeImage = 0 ;
bmih->biXPelsPerMeter = 0 ;
bmih->biYPelsPerMeter = 0 ;
bmih->biClrUsed = 0 ;
bmih->biClrImportant = 0 ;
在基本準備後,我們呼叫該函式:
hBitmap = CreateDIBSection (NULL, (BITMAPINFO *) &bmih, 0, &pBits, NULL, 0) ;

dib注意問題

我們為第二個參數賦予BITMAPINFOHEADER結構的位址。這是常見的,但一個BYIE指標pBits的位址,就不常見了。這樣,第四個參數是函式需要的指向指標的指標。
這是函數調用所做的:CreateDIBSection檢查BITMAPINFOHEADER結構並配置足夠的內存來載入DIB位圖。(在這個例子裏,內存的大小為384×256×3位。)它在您提供的pBits參數中儲存了指向此內存指標。函數返回位圖點陣圖值,正如我説的,它與CreateDIBitmap和其他點陣圖建立函數返回的值不一樣。
然而,我們還沒有做完,點陣圖像素是未初始化的。如果正在讀取DIB文件,可以簡單地把pBits參數傳遞ReadFile函式並讀取它們。