当前位置:首页 > 编程开发

透明位图显示

webgou16年前 (2010-09-15)编程开发292

想到透明位图,找了找资料,有几种实现,并理解了下,掩码机制(其实就是数据的逻辑操作)。

 

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

首先来看一个函数:

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);就可以了。

来源连接:http://blog.csdn.net/iamshuke/archive/2010/07/20/5749897.aspx

参考:VC知识库

扫描二维码推送至手机访问。

版权声明:本文由知了博客发布,如需转载请注明出处。

本文链接:https://www.webgou.info/?id=337

标签: vc mfcvc
分享给朋友:

“透明位图显示” 的相关文章

gAppProxy

gAppProxy 用于访问外国网址:…

Java基础 三步学会Java Socket编程(一)

http://java.ccidnet.com/art/3539/20070606/1103859_1.html第一步 充分理解Socket1.什么是socket所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字&…

Audio 组成

Audio 组成0.直接操作Mixer API 速度会比 waveform audio api速度要快1.Mixer api 控件范围要比waveform audio api 要快.2.Mixer api灵活,可以自行控件。…

从 Z-BlogASP 到 Z-BlogPHP:一次老博客升级迁移记录

很多早年搭建的个人博客,都会遇到同一个问题:程序还能跑,文章也都在,但后台、主题、插件和服务器环境已经明显跟不上了。我的这个站点就是一个典型例子,原来使用的是 Z-BlogASP 老版本,数据放在 Access 数据库里,没有 MySQL,运行环境也比较旧。这次升级的目标不是“换一个全新网站”,而是…

FAT16/23 DBR 格式说明

Boot Sector and BPB Structure…

ATL.SubclassWindow分析

[B]ATL.SubclassWindow分析[/B] [template BOOL CWindowImplBaseT::SubclassWindow(HWND hWnd) { BOOL result; ATLASSUME(m_hWnd == NULL); ATLASSERT(::IsWi…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。