dib

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

基本介紹

  • 中文名:dib
  • 簡介:DIB設備無關點陣圖檔案
  • 類型:一種檔案格式
  • 平台:windows
結構,定義,編寫類,介紹,使用,注意問題,

結構

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可以存儲在*.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像素的邏輯顏色索引轉換成系統調色板索引。

編寫類

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

使用

首先讓我們檢查一下如何簡化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) ;

注意問題

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

相關詞條

熱門詞條

聯絡我們