複製鏈接
請複製以下鏈接發送給好友

SRCINVERT

鎖定
SRCINVERT,指的是透明位圖。
外文名
SRCINVERT
類    別
透明位圖
[1] 
  • 如果一個單色位圖向彩色位圖轉換,那麼單色位圖為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)
參考資料