DDB和DIB 是什么?区别?
BMP圖像文件是Windows ?
?3.X ?
?所采用的圖像文件格式,幾乎所有Wind
ows ?
?上的應用軟件都支持這種圖像文件,其中最常見的就是Windows本身所附的繪圖軟件(Paint-Brush),所以欲在Windows上探討圖像的文件格式,勢必要對BMP有一個完整而全面的認識。 ?
?
?BMP圖像分為兩類,DDB和DIB,DDB(device-dependent ?
?bitmap)即為設備相關位圖,DIB(device-independent ?
?bitmap)即為設備無關位圖。 ?
?
?DDB中不包括顏色信息,顯示時是系統的調色板為基礎進行各位的顏色映射的,Windows只能保證系統調色板的前20種顏色穩定不變,所以DDB只能保證正確顯示色彩少于20色的位圖,這便是局限性。所以現在研究的基本上都是基于DIB的圖像文件。 ?
?
?DIB(設備無關位圖)可以在不同的機器或系統中顯示位圖所固有的顏色。與DDB相比而言,DIB是一種外部的位圖格式,經常存儲以BMP為后綴的位圖文件。DIB位圖還支持圖像數據的壓縮。BMP文件由文件頭、位圖信息頭、顏色信息和圖像數據四部分組成。位圖結構如圖3-1所示: ?
?
??
?
?位圖文件頭結構BITMAPFILEHEADER ?
?
?位圖信息頭結構BITMAPINFOHEADER ?
?
?位圖調色板RGBQUAD ?
?
?位圖像素數據 ?
?
?圖3-1 ?
??
?DIB位圖結構 ?
?
?1. BMP文件頭: ?
?
?BMP文件頭數據結構含有BMP文件的類型、文件大小和位圖起始位置等信息。其結構定義如下: ?
?
?typedef ?
?struct ?
?tagBITMAPFILEHEADER ?
?
?{ ?
?
??
??
?WORD ?
??
?bfType; ?
?
??
??
?WORD ?
??
?bfSize; ?
?
??
??
?WORD ?
??
?bfReserved1; ?
?
??
??
?WORD ?
??
?bfReserved2; ?
?
??
??
?WORD ?
??
?bfOffBits; ?
?
?}BITMAPFILEHEADER,FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER; ?
?
?該結構的長度是固定的,為14個字節,各個域的說明如下: ?
?
? bfType:指定文件類型,必須是0x4d42,即字符串“BM”。 ?
?
? bfSize:指定文件大小,包括這14個字節。 ?
?
? bfReserved1,bfReserved2:保留字,為0。 ?
?
? bfOffBits:從文件頭到實際的位圖數據的偏移字節數,即圖1中前三個部分的長度之和。 ?
?
??
?
?2. ?
?位圖信息頭: ?
?
?BMP位圖信息頭數據用于說明位圖的尺寸等信息。 ?
?
?typedef ?
?struct ?
?tagBITMAPINFOHEADER ?
?
?{ ?
?
??
??
??
?DWORD ?
??
?biSize; ?
?
??
??
??
?LONG ?
??
??
?biWidth; ?
?
??
??
??
?LONG ?
??
??
?biHeight; ?
?
??
??
??
?WORD ?
??
??
?biPlanes; ?
?
??
??
??
?WORD ?
??
??
?biBitCount; ?
?
??
??
??
?DWORD ?
??
?biCompression; ?
?
??
??
??
?DWORD ?
??
?biSizeImage; ?
?
??
??
??
?LONG ?
??
??
?biXPelsPerMeter; ?
?
??
??
??
?LONG ?
??
??
?biYPelsPerMeter; ?
?
??
??
??
?DWORD ?
??
?biClrUsed; ?
?
??
??
??
?DWORD ?
??
?biClrImportant; ?
?
?}BITMAPINFOHEADER,FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER; ?
?
?該結構的長度也是固定的,為40個字節,各個域的說明如下: ?
?
? biSize:指定這個結構的長度,為40個字節。 ?
?
? biWidth:指定圖像的寬度,單位是象素。 ?
?
? biHeight:指定圖像的高度,單位是象素。 ?
?
? biPlanes:必須是1。 ?
?
? biBitCount:指定表示顏色時用到的位數,常用的值為1(黑白二色圖)、4(16色圖)、8(256色圖)、24(真彩色圖)。 ?
?
? biCompression:指定位圖是否壓縮,有效值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows位圖可采用RLE4和RLE8的壓縮格式,BI_RGB表示不壓縮。 ?
?
? biSizeImage:指定實際的位圖數據占用的字節數,可用以下的公式計算出來: ?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
?biSizeImage ?
?= ?
?biWidth’× ?
?biHeight ?
?
??
??
??
??
?要注意的是:上述公式中的biWidth’必須是4的整數倍(不是biWidth,而是大于或等于biWidth的離4最近的整數倍)。如果biCompression為BI_RGB,則該項可能為0。 ?
?
? biXPelsPerMeter:指定目標設備的水平分辨率。 ?
?
? biYPelsPerMeter:指定目標設備的垂直分辨率。 ?
?
? biClrUsed:指定本圖像實際用到的顏色數,如果該值為0,則用到的顏色數為2的biBitCount次冪。 ?
?
? biClrImportant:指定本圖像中重要的顏色數,如果該值為0,則認為所有的顏色數都是重要的。 ?
?
?3. ?
?圖調色板(RGBQUAD): ?
?
?第三部分為調色板。有些位圖需要調色板,有些位圖,如真彩色圖,不需要調色板,它們的BITMAPINFOHEADER后面直接是位圖數據。 ?
?
?調色板實際上是一個數組,共有biClrUsed個元素(如果該值為0,則有2的biBitCount次冪個元素)。數組中每個元素的類型是一個RGBQUAD結構,占4個字節,其數據結構定義如下: ?
?
?typedef ?
?struct ?
?tagRGBQUAD ?
?
?{ ?
?
??
??
??
??
??
??
??
??
??
?BYTE ?
??
??
?rgbBlue; ?
?
??
??
??
??
??
??
??
??
??
?BYTE ?
??
??
?rgbGreen; ?
?
??
??
??
??
??
??
??
??
??
?BYTE ?
??
??
?rgbRed; ?
?
??
??
??
??
??
??
??
??
??
?BYTE ?
??
??
?rgbReserved; ?
?
?}RGBQUAD; ?
?
?其中: ?
?
? rgbBlue:該顏色的藍色分量。 ?
?
? rgbGreen:該顏色的綠色分量。 ?
?
? rgbRed:該顏色的紅色分量。 ?
?
? rgbReserved:保留值。 ?
?
?4. ?
?圖像數據: ?
?
?對于用到調色板的位圖,圖像數據就是該象素顏色在調色板中的索引值,對于真彩色圖,圖像數據就是實際的R、G、B值。 ?
?
? 對于2色圖,用1位就可以表示該象素的顏色,所以1個字節可以表示8個象素。 ?
?
? 對于16色圖,用4位可以表示一個象素的顏色,所以1個字節可以表示2個象素。 ?
?
? 對于256色圖,1個字節剛好可以表示1個象素。 ?
?
? 對于真彩色圖,3個字節才能表示1個象素。 ?
?
?BMP圖像數據的存儲順序是由下往上、由左向右(即圖像上下顛倒存儲),而圖像的寬度(以字節為單位)必須是4的倍數,倘若不到4的倍數則必須補足,并且圖像的數據及其調色板數據存儲格式為BGRBGR…而不是一般習慣的RGBRGB…。?
?
?
?
1。DIB是設備無關位圖,DDB是設備相關位圖,創建位圖句柄時DDB需要傳門創建調色板句柄而DIB就不需要。??
??2。lpvoid都是數據緩沖區,GetDIBits()就是預留存儲圖像數據的區域,而CreateDIBSection()就是需轉換為句餅的圖像數據的區域。??
??3。創建一個DC,將某一DIB句柄與它關聯,將屏幕DC拷貝到該創建DC上。
==================================================================================
1/???DIB一般用于位圖文件(*.BMP),而DDB一般在程序運行中使用??
??2/???SetDIBits()它是將DIB位圖轉換為DDB位圖。比如說你想顯示一個BMP位圖文件,你就??
??可以先從文件頭結構中讀出位圖的大小,然后按照這個尺寸創建一個空位圖句柄,再分配??
??一塊內存,將位圖文件中的位數據讀到這塊內存中。(注意,這個位數據就是DIB格式的)??
??然后再調用SetDIBits()函數,空位圖句柄對應HBITMAP參數,內存地址對應LPVOID參??
??數。成功返回之后,空位圖句柄中位圖的圖像就和文件中的一樣了。你可以拿這個句柄??
??代入象BitBlt()之類的函數中進行各種操作。這個句柄就是DDB位圖句柄。此時,調用前分配的內存塊已經沒用了,可以釋放。??
??????GetDIBits()函數的功能與SetDIBits()相反,它是將你從屏幕或其它途徑獲取的DDB??
??位圖轉換為DIB位圖。轉換后的DIB位數據將保存在LPVOID所指向的內存中。如果你再填寫??
??一個正確的BITMAPINFO結構,那么建立位圖文件就很容易了。?
總結
以上是生活随笔為你收集整理的DDB和DIB 是什么?区别?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]区块链主流开源技术体系介绍
- 下一篇: 蔚来汽车第 2100 座换电站于 G22