如何實現掩碼位圖的透明顯示


位圖的透明顯示一般有兩種機制,即透明色機制和掩碼位圖機制。透明色機制是把位圖中的某種顏色設為透明,掩碼位圖機制是利用一個掩碼位圖來確定要透明的部分。本文只介紹掩碼位圖機制。

首先來看一個函數:

void DrawMaskBmp(CDC *pDC,int nX,int nY,CBitmap &bitmap,CBitmap &maskBitmap)
{
CDC bitmapDC;
CBitmap *pOldBmp1;
BITMAP bmp;
bitmap.GetBitmap(&bmp);
bitmapDC.CreateCompatibleDC(pDC);
pOldBmp1 = bitmapDC.SelectObject(&bitmap);
CDC maskDC;
CBitmap *pOldBmp2;
maskDC.CreateCompatibleDC(pDC);
pOldBmp2 = maskDC.SelectObject(&maskBitmap);
CDC bufDC;
CBitmap bufBitmap,*pOldBmp3;
bufBitmap.CreateCompatibleBitmap(pDC,bmp.bmWidth,bmp.bmHeight);
bufDC.CreateCompatibleDC(pDC);
pOldBmp3 = bufDC.SelectObject(&bufBitmap);
bufDC.BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&bitmapDC,0,0,SRCCOPY);
bufDC.BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&maskDC,0,0,SRCINVERT);
bitmapDC.SelectObject(pOldBmp1);
bitmapDC.DeleteDC();
pDC->BitBlt(nX,nY,bmp.bmWidth,bmp.bmHeight,&maskDC,0,0,SRCAND);
pDC->BitBlt(nX,nY,bmp.bmWidth,bmp.bmHeight,&bufDC,0,0,SRCPAINT);
maskDC.SelectObject(pOldBmp2);
maskDC.DeleteDC();
bufDC.SelectObject(pOldBmp3);
bufDC.DeleteDC();
bufBitmap.DeleteObject();
}

該函數實現了把位圖bitmap透明顯示到pDC的nX、nY位置,maskBitmap是掩碼位圖。它的調用方法如下:

void CMyDialog::MyDraw()
{
CBitmap bitmap,maskBitmap;
bitmap.LoadBitmap(IDB_BITMAP);
maskBitmap.LoadBitmap(IDB_BITMAP_MASK);
CClientDC cdc(this);
DrawMaskBmp(&cdc,85,250,bitmap,maskBitmap);
bitmap.DeleteObject();
maskBitmap.DeleteObject();
}

從函數DrawMaskBmp可以看到,要實現位圖的透明顯示,要經過如下幾個步驟:

1、創建一個要顯示位圖的掩碼位圖;

要顯示的位圖:,掩碼位圖:。掩碼位圖是一個單色位圖,它的黑色部分就是位圖顯示時要保留的部分,白色部分就是要透明的部分。

2、創建一個和該位圖大小一樣的內存位圖和DC(bufBitmap、bufDC),把該位圖用SRCCOPY(拷貝)方式顯示到這個DC中;

3、把掩碼位圖用SRCINVERT(XOR)方式疊加到該內存DC中;

原位圖和掩碼位圖做了XOR操作后,內存DC中的位圖如下所示:,即白色XOR白色=黑色(白色的RGB都是255,1^1=0),黑色XOR任何顏色=原顏色(0^0=0,0^1=1)。

4、把掩碼位圖用SRCAND(AND)方式疊加到pDC中;

and = ,即白色and任何顏色=原顏色(1&1=1,1&0=0),黑色and任何顏色=黑色(0&0=0,0&1=0)。

5、把bufDC用SRCPAINT(or)方式疊加到pDC中。

or =,即黑色or任何顏色=原顏色(0|1=1,0|0=0)。

當然了,上文只是為了說明利用掩碼位圖進行透明顯示的原理,實際應用中用MaskBlt函數更簡單,它的原型如下:

BOOL MaskBlt (
int
x,
int
y,
int
nWidth,
int
nHeight,
CDC*
pSrcDC,
int
xSrc,
int
ySrc,
CBitmap&
maskBitmap,
int
xMask,
int
yMask,
DWORD
dwRop );

針對上述情況,pDC->MaskBlt(nX,nY,bmp.bmWidth,bmp.bmHeight,&bitmapDC,0,0,maskBitmap,0,0,0xccaa0000);就可以了。

補充說明: 0xccaa0000的由來

MaskBlt的最后一個參數是一個四元光柵操作碼,可用MAKEROP4(fore,back)由兩個三元光柵操作碼生成,當maskBitmap中對應的位為1時,采用fore光柵操作碼,否則采用back光柵操作碼。此處fore為0x00AA0000(和目標相同),back為0x00CC0000(和源相同),即maskBitmap中黑色(0)對應部分采用pSrcDC中的圖像,白色(1)對應部分不改變。三元光柵操作碼請參考MSDN中的"Ternary Raster Operations"。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM