如何实现掩码位图的透明显示


本文转载自:http://www.cnblogs.com/lzmfywz/archive/2012/06/29/2569975.html

位图的透明显示一般有两种机制,即透明色机制和掩码位图机制。透明色机制是把位图中的某种颜色设为透明,掩码位图机制是利用一个掩码位图来确定要透明的部分。本文只介绍掩码位图机制。

首先来看一个函数:

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"。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值