SRCINVERT

BitBlt,透明點陣圖,SRCINVERT,SRCAND
  • 如果一個單色點陣圖向彩色點陣圖轉換,那么單色點陣圖為1的部分(也就是白色部分),會轉換為彩色點陣圖的背景色,單色點陣圖為0的部分(黑色部分),會轉換為彩色點陣圖的前景色。
  • 如果一個彩色點陣圖向單色點陣圖轉換,那么彩色點陣圖的背景色轉換到單色點陣圖中則為1(白色),其他的則轉換為0(黑色)。當然上面的1和0都是指bit位的值,還有這些轉換是在設備上下文間的塊數據操作前就進行的。
  • 由於windows上所有的點陣圖操作都是基於記憶體設備上下文的,所以我們還需要創建兩個設備上下文分別用於存放源點陣圖和“掩碼”點陣圖。點陣圖在設備上下文之間塊數據傳遞需要通過Biltblt實現,對於這個函式和關於bitblt的最後一個參數的光柵操作的具體含義的介紹,這裡就不再贅述,具體可看MSDN上關於bilblt的描述。
  • 對一數據做兩次異或操作,那么數據將恢復到原數據,跟沒操作一樣,透明貼圖就是運用該原理。

示例:
CBitmap btfile;
btfile.LoadBitmap(IDB_BITMAP1);
BITMAP btinfo;
btfile.GetBitmap(&btinfo); //獲取源點陣圖的大小等信息
CClientDC dcClient(this); // 當前繪畫DC,以下表述中可能會稱之為“底圖”
CDC dcImage, dcMask; // 創建兩個用於處理點陣圖的兼容記憶體DC,MSDN指出圖片處理需要在記憶體DC中進行
// dcImage 該兼容DC用於處理源彩色點陣圖,而dcMask用於生成跟源圖對應的黑白掩碼點陣圖
dcImage.CreateCompatibleDC(&dcClient); // 跟dcClient兼容
dcImage.SelectObject(&btfile); // 將源彩色點陣圖選人“源圖處理dc”
dcImage.SetBkColor(RGB(255, 255, 255));
//設定背景色,也就是源點陣圖的透明色,假設為白色,我們一般做素材時,將背景做成白色的,
// 在下面,生成掩碼圖時,跟背景相同的會轉換為白色,其他顏色轉換為黑色
CBitmap btSingleColor; // 聲明點陣圖對象
btSingleColor.CreateBitmap(btinfo.bmWidth, btinfo.bmHeight, 1, 1, NULL);// 設定該記憶體點陣圖的大小,並設定為單色點陣圖
dcMask.CreateCompatibleDC(&dcClient); // 跟dcClient兼容
dcMask.SelectObject(&btSingleColor); // 將黑白點陣圖選人“掩碼處理dc”
dcMask.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCCOPY);
//這裡DC之間的塊數據拷貝就用到了開頭提到的知識點,從彩色點陣圖向單色點陣圖轉換,
//源點陣圖的背景圖拷到掩碼DC中後變為白色,其他則為黑色
dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCINVERT);
// 源圖跟底圖進行異或
// SRCINVERT:這個光柵操作碼代表“異或”操作,SRCAND:代表“與”操作
// 如果對一數據做兩次異或操作,那么數據將恢復到原數據,跟沒操作一樣
// 透明點陣圖就是利用這個特性,將源點陣圖異或的方式拷貝到顯示DC兩次
// 但是異或拷貝兩次的話,那么源點陣圖將不顯示,換種說法就是整張點陣圖都被透明了
// 這可不是我們想要的結果,我們的目的只是將背景色透明,所以我們還需要在這兩次
// 異或操作中加入其他操作來實現我們想要的結果,這時候就需要上面準備的“掩碼”DC來幫忙了
dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcMask, 0, 0, SRCAND);
// 掩碼DC內的單色點陣圖跟上面的結果進行與操作,目的是將需要透明的地方保留不變,這樣下次再次用源圖異或時
// 該部分就應為執行了兩次異或而透明了;而最終結果中需要顯示的部分,在本次掩碼與操作中,
// 應當為清除為0,即黑色,這樣下次異或時,將會原封不動的顯示出來。
//掩碼DC內的單色點陣圖為1的部分,將會保留顯示DC的原圖,為0的部分將會清除對應區域為0,即為黑色
dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCINVERT);
// 最後在上面步驟的基礎上,再次用源數據DC進行一下異或操作,
// 最終的結果,需要透明的部分,源圖因為執行了兩次異或,而透明了,直接顯示底圖的圖案
// 需要顯示的部分,因為是跟0異或,將得到完全的保留。
// 異或操作:(0^1 = 1) (0^0 = 0)

相關詞條

熱門詞條

聯絡我們