关于位图背景色透明化的实现

       实现透明位图,有一个知识点必须要提前知道,那就是:

如果一个单色位图向彩色位图转换,那么单色位图为1的部分(也就是白色部分),会转换为彩色位图的背景色,单色位图为0的部分(黑色部分),会转换为彩色位图的前景色。
如果一个彩色位图向单色位图转换,那么彩色位图的背景色转换到单色位图中则为1(白色),其他的则转换为0(黑色)。
当然上面的1和0都是指bit位的值,还有这些转换是在设备上下文间的块数据操作前就进行的。
由于windows上所有的位图操作都是基于内存设备上下文的,所以我们还需要创建两个设备上下文分别用于存放源位图和“掩码”位图。
位图在设备上下文之间块数据传递需要通过Biltblt实现,对于这个函数和关于bitblt的最后一个参数的光栅操作的具体含义的介绍,这里就不再赘述,具体可看MSDN上关于bilblt的描述。
接下去直接看代码,在代码中再通过注释对一些细节进行详细的描述。
       CBitmap btfile;
       btfile.LoadBitmap(IDB_BITMAP1);
 
       BITMAP btinfo;
       btfile.GetBitmap(&btinfo); //获取源位图的大小等信息
 
       CClientDC dcClient(this);
       CDC dcImage, dcMask;
    //分别创建对预显示位图的DC的兼容DC
       dcImage.CreateCompatibleDC(&dcClient);
       dcMask.CreateCompatibleDC(&dcClient);
 
       CBitmap btSingleColor;
    //创建单色位图
       btSingleColor.CreateBitmap(btinfo.bmWidth, btinfo.bmHeight, 1, 1, NULL);
    //载入源位图
       dcImage.SelectObject(&btfile);
    //设置背景色,也就是源位图的透明色
       dcImage.SetBkColor(RGB(255, 0, 0));
    //载入单色位图
       dcMask.SelectObject(&btSingleColor);
//这里DC之间的块数据拷贝就用到了开头提到的知识点,从彩色位图向单色位图转换,
//源位图的背景图拷到掩码DC中后变为白色,其他则为黑色
       dcMask.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCCOPY);
    //设置显示DC的背景色和前景色
       COLORREF color1 = dcClient.SetBkColor(RGB(255, 255, 255));
       COLORREF color2 = dcClient.SetTextColor(RGB(0, 0, 0));
// SRCINVERT:这个ROP代表异或位操作,SRCAND:代表与操作
//如果对一数据做两次异或操作,那么数据将恢复到原数据,跟没操作一样
//透明位图就是利用这个特性,将源位图异或的方式拷贝到显示DC两次
//但是只拷贝两次的话,那么源位图将不显示,换种说法就是整张位图都被透明了
//这可不是我们想要的结果,我们的目的只是将背景色透明,所以我们还需要在这两次//异或操作中加入其他操作来实现我们想要的结果,这时候就需要上面准备的“掩码”//DC来帮忙了
       dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCINVERT);
    //解决这个问题其实很简单,就是维持背景色不变,这样它在下次异或操作后会恢复源//数据,被透明了;然后将前景色变黑。
    //掩码DC内的单色位图为1的部分,将会转换为显示DC的背景色,为0的部分转换//为显示DC的前景色,然后再与显示DC的块数据做与(SRCAND)操作,在位操作后,//背景色维持不变,前景色为0(黑色)
       dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcMask, 0, 0, SRCAND);
    //然后源数据DC再与显示DC的数据块再做一次异或操作的,背景色恢复为显示DC
//的图像数据,前景色则显示为源数据DC内的图像数据(0^1 = 1)
       dcClient.BitBlt(0, 0, btinfo.bmWidth, btinfo.bmHeight, &dcImage, 0, 0, SRCINVERT);
    //恢复显示DC的前景和背景色
       dcClient.SetBkColor(color1);
       dcClient.SetTextColor(color2);
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值