如何画透明位图

如何画透明位图

  画透明位图通常的方法是使用遮罩。所谓遮罩就是一张黑白双色的位图,他和要透明的位图是对应的,遮罩描述了位图中需要透明的部分,透明的部分是黑色的,而不透明的是白色的,白色的部分就是透明的部分。
  假设图A是要画的透明位图,图B是遮罩,图A上是一个大写字母A,字母是红色的,背景是黑色的,图B背景是白色的,上面有一个黑色的字母A和图A的形状是一样的。比如我们要在一张蓝天白云的背景上透明地画图A,就是只把红色的字母A画上去。我们可以先将图B和背景进行与操作,再把图B和背景进行或操作就可以了。

用VC++ MFC实现的代码如下:

void CDemoDlg::OnPaint()
{
   CPaintDC dc(this);

   Cbitmap BmpBack,BmpA,BmpB,*pOldBack,*pOldA,*pOldB;

   BmpBack.LoadBitmap(IDB_BACKGROUND); // 载入背景图

   BmpA.LoadBitmap(IDB_BITMAPA); //载入图A

   BmpB.LoadBitmap(IDB_BITMAPB); //载入图B

   CDC dcBack,dcA,dcB; //声明三个内存DC用于画图

   dcBack.CreateCompatibleDC(&dc);

   dcA.CreateCompatibleDC(&dc);

   dcB.CreateCompatibleDC(&dc); //把这三个内存DC创建成和PaintDC兼容的DC

   pOldBack=dcBack.SelectObject(&BmpBack);

   pOldA=dcA.SelectObject(&BmpA);

   pOldB=dcB.SelectObject(&BmpB); //把三个位图选入相应的DC
   
   dc.BitBlt(0,0,100,100,&dcBack,0,0,SRCCOPY); //画背景
   dc.BitBlt(0,0,48,48,&dcB,0,0,SRCAND); //用与的方式画遮罩图B
   dc.BitBlt(0,0,48,48,&dcA,0,0,SRCPAINT); //用或的方式画遮图A
   
   dcBack.SelectObject(pOldBack);
   dcBack.SelectObject(pOldA);
   dcBack.SelectObject(pOldB); //从内存DC中删除位图
}

  你会看到红色的字母A透明地画在背景上了。用遮罩的方法必须事先做好遮罩,遮罩和位图大小一样等于多消耗一倍的资源,比较浪费。还有一种画透明位图的方法,基本原理是一样的,只是不用事先做好遮罩,根据需要动态生成遮罩,但是要求需要透明的位图必须指定一种透明色,凡是这个透明色的地方则画成透明的。

用VC++ MFC实现的代码如下,这是一个用来画透明位图的函数:

CDC *pDC 需要画位图的CDC指针,
UINT IDImage 位图资源ID,
Crect &rect 指定位图在pDC中的位置,
COLORREF rgbMask 位图的透明色

void DrawTransparentBitmap(CDC *pDC, UINT IDImage,Crect &rect, COLORREF rgbMask)
{
   CDC ImageDC,MaskDC;

   Cbitmap Image,*pOldImage;

   Cbitmap maskBitmap,*pOldMaskDCBitmap ;

   Image.LoadBitmap(IDImage);

   ImageDC.CreateCompatibleDC(pDC);

   pOldImage=ImageDC.SelectObject(&Image);

   MaskDC.CreateCompatibleDC(pDC);

   maskBitmap.CreateBitmap( rect.Width(), rect.Height(), 1, 1, NULL );

   pOldMaskDCBitmap = MaskDC.SelectObject( &maskBitmap );

   ImageDC.SetBkColor(rgbMask);

   MaskDC.BitBlt( 0, 0, rect.Width(), rect.Height(), &ImageDC, 0, 0, SRCCOPY );

   ImageDC.SetBkColor(RGB(0,0,0));
   ImageDC.SetTextColor(RGB(255,255,255));
   ImageDC.BitBlt(0, 0, rect.Width(), rect.Height(), &MaskDC, 0, 0, SRCAND);

   pDC->BitBlt(rect.left,rect.top,rect.Width(), rect.Height(), &MaskDC, 0, 0, SRCAND);
   pDC->BitBlt(rect.left,rect.top,rect.Width(), rect.Height(), &ImageDC, 0, 0,SRCPAINT);

   MaskDC.SelectObject(pOldMaskDCBitmap);
   ImageDC.SelectObject(pOldImage);
}

void CDemoDlg::OnPaint()
{
   CPaintDC dc(this);
   Cbitmap BmpBack,*pOldBack,;

   BmpBack.LoadBitmap(IDB_BACKGROUND);

   CDC dcBack;
   dcBack.CreateCompatibleDC(&dc);

   pOldBack=dcBack.SelectObject(&BmpBack);
   dc.BitBlt(0,0,100,100,&dcBack,0,0,SRCCOPY);
   DrawTransparentBitmap(&dc,IDB_BITMAPA,Crect(0,0,48,48),RGB(192,192,0));
   dcBack.SelectObject(pOldBack);

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值