SRCINVERT

SRCINVERT

dcClien dcClien dcClien

目錄

正文


透明點陣圖--SRCINVERT用法講解
如果一個單色點陣圖向彩色點陣圖轉換,那麼單色點陣圖為1的部分(也就是白色部分),會轉換為彩色點陣圖的背景色,單色點陣圖為0的部分(黑色部分),會轉換為彩色點陣圖的背景色。如果一個彩色點陣圖向單色點陣圖轉換,那麼彩色點陣圖的背景色轉換到單色點陣圖中則為1(白色),其他的則轉換為0(黑色)。當然上面的1和0都是指bit位的值,還有這些轉換是在設備上下文間的塊數據操作前就進行的。由於windows上所有的點陣圖操作都是基於內存設備上下文的,所以我們還需要創建兩個設備上下文分別用於存放源點陣圖和“掩碼”點陣圖。
點陣圖在設備上下文之間塊數據傳遞需要通過Biltblt實現,對於這個函數和關於bitblt的最後一個參數的光柵操作的具體含義的介紹,這裡就不再贅述,具體可看MSDN上關於bilblt的描述。
接下去直接看代碼,在代碼中再通過註釋對一些細節進行詳細的描述。
CBitmapbtfile;
btfile.LoadBitmap(IDB_BITMAP1);
BITMAP btinfo;
btfile.GetBitmap(&btinfo); //獲取源點陣圖的大小等信息
CClientDCdcClient(this);
CDC dcImage, dcMask; //分別創建對預顯示點陣圖的DC的兼容
DC dcImage.CreateCompatibleDC(&dcClient);
dcMask.CreateCompatibleDC(&dcClient);
CBitmap btSingleColor; //創建單色點陣圖
btSingleColor.CreateBitmap(btinfo.bmWidth, btinfo.bmHeight, 1, 1, NULL); //載入源點陣圖 dcImage.SelectObject(&btfile); //設置背景色,也就是源點陣圖的透明色
dcImage.SetBkColor(RGB(255, 0, 0)); //載入單色點陣圖
dcMask.SelectObject(&btSingleColor);//這裡DC之間的塊數據拷貝就用到了開頭提到的知識點,從彩色點陣圖向單色點陣圖轉換,//源點陣圖的背景圖拷到掩碼DC中后變為白色,其他則為黑色
dcMask.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCCOPY); //設置顯示DC的背景色和前景色
COLORREFcolor1 = dcClient.SetBkColor(RGB(255, 255, 255));
COLORREF color2 = dcClient.SetTextColor(RGB(0, 0, 0));// SRCINVERT:這個ROP代表異或位操作,SRCAND:代表與操作//如果對一數據做兩次異或操作,那麼數據將恢復到原數據,跟沒操作一樣//透明點陣圖就是利用這個特性,將源點陣圖異或的方式拷貝到顯示DC兩次//但是只拷貝兩次的話,那麼源點陣圖將不顯示,換種說法就是整張點陣圖都被透明了//
這可不是我們想要的結果,我們的目的只是將背景色透明,所以我們還需要在這兩次//異或操作中加入其他操作來實現我們想要的結果,這時候就需要上面準備的“掩碼”//DC來幫忙了
dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCINVERT); //解決這個問題其實很簡單,就是維持背景色不變,這樣它在下次異或操作後會恢復源//數據,被透明了;然後將前景色變黑。 //掩碼DC內的單色點陣圖為1的部分,將會轉換為顯示DC的背景色,為0的部分轉換//為顯示DC的前景色,然後再與顯示DC的塊數據做與(SRCAND)操作,在位操作后,//背景色維持不變,前景色為0(黑色)
dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcMask, 0, 0, SRCAND); //然後源數據DC再與顯示DC的數據塊再做一次異或操作的,背景色恢復為顯示DC//的圖像數據,前景色則顯示為源數據DC內的圖像數據(0^1 = 1)
dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCINVERT);
//恢復顯示DC的前景和背景色
dcClient.SetBkColor(color1); dcClient.SetTextColor(color2);