標籤:
Windows調色盤是256色顯卡時期的產物,如今顯卡最少也是16bit的了。所以調色盤基本上是用不到了的。
可是以下幾種情況還是須要去使用和瞭解調色盤:
1.在新顯卡上保證256色相容模式的正常執行
2.在256色顯卡或低於256色顯卡老機器上執行程式或在一些工業控制場合(為了節約成本可能採用256色顯卡或低於256色顯卡)執行程式
3.操作DIB的指定像素點資料
1.調色盤是什麼
相同採用以下一張圖
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VuemhvdTEyMTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >
如,我們能夠調色盤分為例如以下幾種:
1.DIB檔案裡的調色盤
2.記憶體中建立的邏輯調色盤對象
3.顯卡中硬體調色盤
調色盤顧名思義就是類似畫家的調色盤一樣,以256色顯卡來說,如今有256個小格子,每一個格子中有一種顏色,每次畫圖你能夠用這256種顏色來畫圖,假設你對當前的256種顏色不愜意,能夠更換當中的調色盤顏色,可是每畫一幅圖僅僅能用確認的256中顏色來。相應到電腦的調色盤來說,顯卡支援顯示的顏色僅僅有256種,儲存在顯卡硬體調色盤中,你能夠設定要採用的256種顏色。然後你要顯示的全部顏色都會近似用256中顏色中的一種來顯示,這就是所謂的調色盤查表以取得近期似顏色。
能夠看到。一幅圖在電腦上顯示的效果是什麼樣和當前顯卡硬體調色盤中的顏色是密不可分的,所以對於採用硬體調色盤的的位元影像,儲存它的最好做法就是儲存位元影像資料的同一時候儲存位元影像調色盤。
為了改變硬體調色盤中的顏色我們須要先建立邏輯調色盤對象,然後再將邏輯調色盤映射到硬體調色盤上。
2.調色盤的使用
對於帶有調色盤的DIB來說。顯示DIB的一般過程例如以下:
1.讀入DIB分別為File Header、Info Header、Mask、Color Table、Bits各個區
2.利用DIB的調色盤資料(Color Table區)建立邏輯調色盤對象(CreatePalette)。一般在WM_CREATE中
3.在WM_PAINT顯示DIB之前,將基於DIB建立的邏輯調色盤對象選進當前裝置描寫敘述表(SelectPalette)並映射到硬體調色盤上(RealizePalette)。
4.假設僅僅是想保證指定表單為活動表單時顯示的顏色,那麼做完這三歩即可了。假設想保證指定表單不是活動表單時的顏色,那麼還要處理WM_QUERYPALETTE和WM_PALETTECHANGED訊息。
這兩個訊息是為了協助Windows組織系統調色盤用的。這裡不詳述。直接依照固定模式使用,詳細能夠查看MSDN。
3.代碼示範
示範程式為一個典型的Windows 帶調色盤DIB的顯示過程。以下為部分代碼,完整源碼最後會給出下載連結。
依據DIB Color Table建立邏輯調色盤
//建立資料顯示調色盤HPALETTE PackedDibCreatePalette(BITMAPINFO *pPackedDib, HWND hwnd){HPALETTEhPalete;HDChdc;inti, iNumColors;LOGPALETTE*plp= NULL;RGBQUAD*prgb= NULL;if (0 == PackedDibGetColorTableSize(pPackedDib) && PackedDibGetBitCount(pPackedDib) > 8)//沒有調色盤區且位深大於8,則沒有必要建立調色盤{return NULL;}else if (0 == PackedDibGetColorTableSize(pPackedDib))//沒有調色盤區且位深小於等於8,則建立通用調色盤{hdc = GetDC(hwnd);hPalete = CreateHalftonePalette(hdc);ReleaseDC(hwnd, hdc);return hPalete;}else//使用位元影像內建的調色盤區{iNumColors = PackedDibGetNumColors(pPackedDib);plp = malloc(sizeof(LOGPALETTE) + (iNumColors-1)*sizeof(PALETTEENTRY));if (NULL == plp){return NULL;}plp->palVersion= 0x0300;plp->palNumEntries= iNumColors;for (i = 0; i < iNumColors; i++){prgb = PackedDibGetColorTableEntry(pPackedDib, i);plp->palPalEntry[i].peRed = prgb->rgbRed;plp->palPalEntry[i].peGreen = prgb->rgbGreen;plp->palPalEntry[i].peBlue = prgb->rgbBlue;plp->palPalEntry[i].peFlags = 0;}hPalete = CreatePalette(plp);if (INVALID_HANDLE_VALUE == hPalete){return NULL;}return hPalete;}}
WM_PAINT中顯示DIB及WM_QUERYPALETTE和WM_PALETTECHANGED訊息的處理
case WM_PAINT: hdc = BeginPaint (hwnd, &ps);if (hPalette){SelectPalette(hdc, hPalette, FALSE);RealizePalette(hdc);}if (pPackedDib){SetDIBitsToDevice(hdc, 0, 0, PackedDibGetWidth(pPackedDib), PackedDibGetHeight(pPackedDib), 0, 0,0, PackedDibGetHeight(pPackedDib),PackedDibGetBitsPtr(pPackedDib),pPackedDib,DIB_RGB_COLORS);} EndPaint (hwnd, &ps); return (0);case WM_QUERYNEWPALETTE:if(!hPalette){return FALSE;}hdc = GetDC(hwnd);SelectPalette(hdc, hPalette, FALSE);RealizePalette(hdc);InvalidateRect(hwnd, NULL, FALSE);ReleaseDC(hwnd, hdc);return TRUE;case WM_PALETTECHANGED:if(!hPalette || (HWND)wParam==hwnd){break;}hdc = GetDC(hwnd);SelectPalette(hdc, hPalette, FALSE);RealizePalette(hdc);UpdateColors(hdc);ReleaseDC(hwnd, hdc);break;
4.DIB操作庫
至此為止,關於DIB顯示的所有知識點所有講完。在給出的代碼中實現了一個完整的DIB操作庫,主要用於開啟、顯示和儲存DIB。不同於實驗DIB顯示功能,一個完整性好的DIB操作庫必須相容各種版本號碼DIB格式、不標準DIB位元影像。
1.DIB版本號碼的相容主要包含對OS/2格式位元影像的相容(BITMAPCOREHEADER定義帶來的各種差異。RGBTRIPLE帶來的差異)。
2.不標準DIB位元影像主要指有的DIB位元影像不填充ClrUsed、SizeImage項,有的小於8bit的DIB位元影像沒有調色盤須要使用通用調色盤,有的16bit位元影像不提供掩碼等等。
總之,一個實現完整的DIB庫須要考慮種種繁枝末節,假設是在商業程式中使用的話。最好使用已經開源的各種實現。該博文提供的DIB庫在Pelzold的實現上改動而來,但仍然有不足,比如對壓縮的DIB沒有考慮等,僅供技術研究用。
完整源碼下載連結
原創。轉載請註明來自http://blog.csdn.net/wenzhou1219
Windows DIB檔案操作具體解釋-5.DIB和調色盤