windows下透明位图的绘制

  本文介绍两种用GDI函数实现绘制位图时只绘制除指定颜色外的部分,达到“透明”的 效果 的方法:  
  1. 用BitBlt实现位图上某种颜色的透明显示  
  2. 用MaskBlt实现位图上某种颜色的透明显示  
   
  为 方便 起见,用MFC方式讨论。先有如下的定义:  
  CDC                       *pDC;                       //   目标DC,假设已Create,位图已选入  
  CDC                       *pActiveDC;           //   装载位图的DC。假设已Create,位图已选入  
  CDC                       *pMaskDC;               //   装有掩码位图的DC  
  CBitmap               bmpMask;                 //   MaskDC上使用的位图  
  COLORREF             crTrans;                 //   pActiveDC上需要被透明处理的颜色  
  CRect                   crClient;               //   pDC的大小。假设已获得  
   
  这样,直观的说,本文讨论的目标就是,把pActiveDC绘制到pDC上的时候,不绘制跟crTrans相同的颜色的部分。  
  1. 用BitBlt   API进行透明 显示 的步骤:  
  ①   处理pMaskDC为黑白DC,使pActiveDC上颜色为crTrans的部分在pMaskDC显示为白色,其余地方显示为黑色。  
  ②   将pActiveDC用BitBlt绘制到pDC上,使用SRCINVERT方式  
  ③   将pMaskDC用BitBlt绘制到pDC上,使用SRCAND方式  
  ④   再将pActiveDC用BitBlt绘制到pDC上,使用SRCINVERT方式  
   
  ROP(光栅操作)中,SRCINVERT是位图间异或处理,SRCAND是位图间与处理。可以简单证明上述的操作过程会得到我们想要的结果:  
  对于某一个位置,pDC上颜色为B,pActiveDC上颜色为A。  
  当A   ==   crTrans的时候,pMaskDC上这个位置的颜色M为白色。则上面的②~④步可以表示为:  
  ((B   xor   A)   and   M)   xor   A  
  ⇔   (B   xor   A)   xor   A  
  ⇔   B  
  当A   !=   crTrans的时候,pMaskDC上这个位置的颜色M为黑色。则上面的②~④步可以表示为:  
  ((B   xor   A)   and   M)   xor   A  
  ⇔   0   xor   A  
  ⇔   A  
  下面是实现 代码 :  
  //   Sample   of   demonstrating   making   a   color   transparent.   Pomelo   Wu   on   29/4/2005  
  //   Make   the   Mask   DC   monochrome  
  pMaskDC->CreateCompatibleDC(pDC);  
  bmpMask.CreateBitmap(rcClient.Width(),   rcClient.Height(),    
                                                                          1,   1,   NULL);           //   monochrome   bitmap  
  CBitmap   *   pOldMaskBmp   =   pMaskDC->SelectObject(&bmpMask);  
  //   Set   the   mask   bitmap  
  pActiveDC->SetBkColor(crTrans);  
  pMaskDC->BitBlt(0,   0,   rcClient.Width(),   rcClient.Height(),   pActiveDC,  
                                                                          0,   0,   SRCCOPY);  
  //   Do   the   painting  
  pDC->BitBlt(0,   0,   rcClient.Width(),   rcClient.Height(),   pActiveDC,  
                                                                            0,   0,   SRCINVERT);  
  pDC->BitBlt(0,   0,   rcClient.Width(),   rcClient.Height(),   pMaskDC,  
                                                                            0,   0,   SRCAND);  
  pDC->BitBlt(0,   0,   rcClient.Width(),   rcClient.Height(),   pActiveDC,  
                                                                            0,   0,   SRCINVERT);  
  //   Omit   the   resting   of   destroying   GDI   object  
   
   
  2. 为达到透明的效果,还可以用一种更方便的办法——使用MaskBlt这个API,具体方法如下:  
  ①   pMaskDC选入bmpMask。  
  ②   处理pMaskDC,把需要透明的颜色填充满整个pMaskDC。  
  ③   将pActiveDC用MaskBlt绘制到pDC上, 使用 ROP   code   0xccaa0000方式  
   
  实现代码如下:  
  //   Sample   of   demonstrating   making   a   color   transparent.   Pomelo   Wu   on   29/4/2005  
  //   ROP   code   definition  
  #define   ROP_TRANS                                 0xccaa0000  
  //   handling   the   mask   bitmap  
  pMaskDC->CreateCompatibleDC(pDC);  
  bmpMask.CreateBitmap(rcClient.Width(),   rcClient.Height(),    
                                                                        1,   1,   NULL);           //   monochrome   bitmap  
  CBitmap   *   pOldMaskBmp   =   pMaskDC->SelectObject(&bmpMask);  
  pMaskDC->   FillSolidRect(rcClient,   crTrans);  
  pDC->MaskBlt(0,   0,   rcClient.Width(),   rcClient.Height(),    
                                                                            pActiveDC,   0,   0,    
                                                                            bmpMask,   0,   0,   ROP_CODE_TRANS);  
  //   Omit   the   resting   of   destroying   GDI   object   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值