您的位置:首页 > 其它

VC——位图的透明显示

2010-02-09 08:40 405 查看
这里大部分内容摘自http://www.vckbase.com/document/viewdoc/?id=532 王俊的《透明位图的显示》。自己在看程序的过程中,遇到一些问题,所以进行少量的补充和说明。

包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。

1、TransparentBlt 函数的使用

TransparentBlt 函数在Windows98/Windows2000以上版本运行,系统中需要包含 Msimg32.dll,使用时可以链接 Msimg32.lib。
Windows98下的TransparentBlt会产生资源泄漏,所以不建议在WIN98下使用该函数。
TransparentBlt函数原型如下:

BOOL TransparentBlt(
HDC hdcDest, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int hHeightDest, // 目标高度
HDC hdcSrc, // 源DC
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
);掩码位图

原图 掩码图

2、自己的代码实现类似TransparentBlt的功能

有时候只有原图,而没有相应的掩码图,这时就要通过程序生成掩码图。

为了理解具有透明色位图的绘制过程,建立一个具有同TransparentBlt功能一致的实验函数,称之为TransparentBlt2。
实验素材:有两张位图:bk.bmp是背景位图,football.bmp包含透明区域,透明色为蓝色RGB(0,0,255)
实验目的:以bk.bmp为背景,将football.bmp绘制到背景中,形成如下的最终效果图。



2.1 透明位图绘制原理
假设football.bmp 已经载入到 HBITMAP hImageBMP中 ,hImageBMP已经选入到HDC hImageDC中

2.1.1 生成足球的单色掩码位图,透明区域为白色(全1),非透明区域为黑色(全0)

HBITMAP hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 建立单色位图
SetBkColor(hImageDC, RGB(0,0,255)); // 设置背景色为蓝色

为什么要设置背景色?因为hMaskBMP和hImageBMP的颜色格式是不一样的。在使用BitBlt时,会把原颜色格式转换成目标颜色格式,也就是说会把hImageBMP的彩色格式转换成单色格式(不会影响原图),再进行SRCCOPY。在这种情况下,彩色位图中所有和背景色一致的象素都变成1,其他的象素都被转换成0。
BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); // 拷贝到hMaskDC这样足球位图中蓝色区域在掩码位图中成了白色,其它区域为黑色,此时hMaskBMP 如下图:



(图一)
2.1.2 使原图的蓝色背景色改为黑色的背景色

SetBkColor(hImageDC, RGB(0,0,0));
SetTextColor(hImageDC, RGB(255,255,255));

为什么又要设置背景色和前景色?在将单色转换成彩色时,位为0的地方转换成目的DC的前景色,位为1的地方转换成目的DC的背景色,也就是说hMaskBMP原来的黑色区域变为RGB(255,255,255)白色,原来的白色区域变为RGB(0,0,0)黑色。再与原图相“与”。原图变成如图二所示
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);此时hImageBMP 如下图:



(图二)
2.1.3 给背景“打洞”

SetBkColor(hdcDest,RGB(255,255,255));
SetTextColor(hdcDest,RGB(0,0,0));

同2.1.2中一样,hMaskBMP原来的黑色区域变为RGB(0,0,0)黑色,白色变为白色,就是不变。再与背景图相“与”,背景图如图三所示
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);背景显示如下:



(图三)
2.1.4 将hImageBMP(图二)与背景(图三)进行“或”运算

BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);这样就将足球绘制到背景上了。



2.2 TransparentBlt2函数全部实现代码

void TransparentBlt2( HDC hdcDest, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
HDC hdcSrc, // 源DC
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
)
{
HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图
HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图
HDC hImageDC = CreateCompatibleDC(hdcDest);
HDC hMaskDC = CreateCompatibleDC(hdcDest);
hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

// 将源DC中的位图拷贝到临时DC中
if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
else
StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

// 设置透明色
SetBkColor(hImageDC, crTransparent);

// 生成透明区域为白色,其它区域为黑色的掩码位图
BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);

// 生成透明区域为黑色,其它区域保持不变的位图
SetBkColor(hImageDC, RGB(0,0,0));
SetTextColor(hImageDC, RGB(255,255,255));
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

// 透明部分保持屏幕不变,其它部分变成黑色
SetBkColor(hdcDest,RGB(255,255,255));
SetTextColor(hdcDest,RGB(0,0,0));
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

// "或"运算,生成最终效果
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);

// 清理、恢复
SelectObject(hImageDC, hOldImageBMP);
DeleteDC(hImageDC);
SelectObject(hMaskDC, hOldMaskBMP);
DeleteDC(hMaskDC);
DeleteObject(hImageBMP);
DeleteObject(hMaskBMP);
}

转自:http://blog.csdn.net/oeg2006/archive/2009/11/26/4877722.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: