总结:使用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
绘制背景位图
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 函数实现透明位图处理,应该是这三种实现方法中最为简单,也是最容易理解的。而且,使用起来还比较简洁灵活。