分享

使用TransparentBlt函数实现绘制透明位图

 猎狐肥 2021-07-16

总结:使用TransparentBlt 函数,指定透明色

函数介绍

TransparentBlt 函数

对指定的源设备环境中的矩形区域像素的颜色数据进行位块(bit_block)转换,并将结果置于目标设备环境。

函数声明

复制代码
BOOL TransparentBlt(
      HDC hdcDest, 
      int nXOriginDest, 
      int nYOriginDest, 
      int nWidthDest, 
      int hHeightDest, 
      HDC hdcSrc, 
      int nXOriginSrc, 
      int nYOriginSrc, 
      int nWidthSrc, 
      int nHeightSrc, 
      UINT crTransparent
  );
复制代码

参数

  • hdcDest:指定目标的句柄。

  • nXOriginDest:指定目标矩形左上角的X轴坐标,坐标以逻辑单位表示。

  • nYOriginDest:指定目标矩形左上角的Y轴坐标,坐标以逻辑单位表示。

  • nnWidthDest:指定目标矩形的宽度。

  • nHeightDest:指定目标矩形的高度。

  • hdcSrc:源图的句柄。

  • nXOriginSrc:指定源矩形(左上角)的X轴坐标,坐标以逻辑单位表示。

  • nYOriginsrc:指定源矩形(左上角)的Y轴坐标,坐标以逻辑单位表示。

  • nWidthSrc:指定源矩形的宽度。

  • nHeightSrc:指定源矩形的高度。

  • crTransparent:源位图中的RGB值当作透明颜色。(用RGB(0,0,0)也就是黑色不行)。

返回值

  • 如果函数成功,那么返回TRUE;如果函数失败,则返回FALSE。

什么是位图透明处理?

至于如何使用 BitBlt 函数绘制位图,我在《BMP位图的绘制》这篇有讲过,当然这只是其中一种绘图方法而已,并不是唯一的。

那我就先来介绍下,什么是透明位图的绘制。用下面的图片直观表示吧:

如果我们有两张图片,一张是背景图:

一张是人物图:

现在,我想把人物绘制到背景图上,那么按照通常的方法就是,把人物的图片直接在背景图上显示就好,效果如下所示:

大家可能会看到有些问题了吧,我们其实想要的是下面这张图片的效果:

没错,所谓的透明位图的绘制就像上面图片表示出来的那样。就是我们只绘制图片特定的地方,而且形状都是不规则的,其他的不进行绘制。就对上上面的例子来说,就是把人物抠出来绘制,背景的蓝色不绘制,即背景像似透明一样,所以这便是位图的透明绘制。

编程实现原理

对于,TransparentBlt 函数来说,它的最后一个参数指定除黑色RGB(0, 0, 0)外的其它透明颜色。所谓的透明颜色是指,只要是指定RGB值的颜色,使用Transparent函数都不会绘制,只绘制其他非指定透明颜色RGB值的颜色。

对于上面的例子来说,我们只要指定透明颜色RGB为蓝色(0, 0, 255),这样,就可以不绘制蓝色,而只绘制非蓝色部分的人物图像了。

对于,为何指定了透明颜色,就可以实现透明处理,其本质的原理可以参考我写的《使用BitBlt函数实现绘制透明位图》和《使用StretchBlt函数实现绘制透明位图》这两篇文章中的透明原理的分析。Transparent 函数的实现,应该是调用 StretchBlt 函数去实现的。

编码实现

导入库文件

#include <WinGDI.h>#pragma comment(lib, "Msimg32.lib")

绘制背景位图

复制代码
BOOL PaintBmp(HWND hWnd)
{// 获取窗口的客户区域的显示设备上下文环境的句柄HDC hDC = ::GetDC(hWnd);// 创建一个与hDC兼容的内存设备上下文环境HDC hBuf = ::CreateCompatibleDC(hDC);// 加载位图, 获取位图句柄HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "image\\bg.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);// 选择位图句柄到hBuf中, 并获取返回的原来位图句柄HBITMAP hOldBmp = (HBITMAP)::SelectObject(hBuf, hBmp);// 绘图::BitBlt(hDC, 0, 0, 764, 397, hBuf, 0, 0, SRCCOPY);// 还原位图对象::SelectObject(hBuf, hOldBmp);// 释放位图::DeleteObject(hBmp);// 释放兼容的内存设备上下文环境::DeleteDC(hBuf);// 释放设备上下文环境::ReleaseDC(hWnd, hDC);return TRUE;
}
复制代码

绘制透明位图

复制代码
BOOL PaintTransparentBmp(HWND hWnd)
{// 获取窗口的客户区域的显示设备上下文环境的句柄HDC hDC = ::GetDC(hWnd);// 创建一个与hDC兼容的内存设备上下文环境HDC hBuf = ::CreateCompatibleDC(hDC);// 加载位图, 获取位图句柄HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "image\\1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);// 选择位图句柄到hBuf中, 并获取返回的原来位图句柄HBITMAP hOldBmp = (HBITMAP)::SelectObject(hBuf, hBmp);// 透明色为蓝色 绘制::TransparentBlt(hDC, 280, 210, 200, 200, hBuf, 0, 0, 101, 121, RGB(0, 0, 255));// 还原位图对象::SelectObject(hBuf, hOldBmp);// 释放位图::DeleteObject(hBmp);// 释放兼容的内存设备上下文环境::DeleteDC(hBuf);// 释放设备上下文环境::ReleaseDC(hWnd, hDC);return TRUE;
}
复制代码

程序测试

调用上述封装好的函数,直接测试。人物位图成功背景透明绘制到背景图上。而且,人物还能成功拉伸绘制。

   

总结

使用 TransparentBlt 函数实现透明位图处理,应该是这三种实现方法中最为简单,也是最容易理解的。而且,使用起来还比较简洁灵活。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多