背景
在自己的系里,我喜欢用VC6.0写一个小游戏来锻炼编程水平。 这些小游戏的游戏画面的绘制都是使用Windows提供的图形设备接口(GDI )函数实现的,没有调用现成的游戏引擎。 所以,我对GDI函数比较熟悉,可以用它开发各种游戏了。
其中,用于那些小游戏的一个重要技术是透明位图的绘制。 这里总结了到目前为止自己开发小游戏时,绘制透明位图的方法,分别介绍三种实现方法。 一种是使用BitBlt函数实现。 第二,使用StretchBlt函数实现;第三,使用TransparentBlt函数实现。
这三种方法分别写一次文档进行介绍,本文介绍TransparentBlt函数实现透明位图的绘制。
函数介绍
TransparentBlt函数将指定源设备环境中矩形区域像素的颜色数据转换为位块(bit_block ),并将结果放置在目标设备环境中。
函数声明
BOOLTransparentBlt (
硬盘硬盘est,
intnXOriginDest,
intnYOriginDest,
intnWidthDest、
inthHeightDest,
硬盘硬盘SRC,
intnXOriginSrc、
intnYOriginSrc,
intnWidthSrc、
intnHeightSrc、
uint Cr传输
);
参数
hdcDest :指定目标的句柄。
nXOriginDest :指定目标矩形左上角的x轴坐标。 坐标以逻辑单位表示。
nYOriginDest :指定目标矩形左上角的y轴坐标。 坐标以逻辑单位表示。
nnWidthDest:指定目标矩形的宽度。
nHeightDest :指定目标矩形的高度。
hdcSrc :源图的句柄。
指定nXOriginSrc (源矩形(左上角)的x轴坐标。 坐标以逻辑单位表示。
指定nYOriginsrc (源矩形(左上角)的y轴坐标。 坐标以逻辑单位表示。
nWidthSrc :指定源矩形的宽度。
nHeightSrc :指定源矩形的高度。
crTransparent :使用源位图的RGB值作为透明颜色。 (RGB (0,0,0 )也就是说黑色是不行的。
返回值
如果函数成功,则返回TRUE; 如果函数失败,则返回FALSE。
什么是位图透射处理?
我们在《BMP位图的绘制》这篇文章中讨论了如何使用BitBlt函数绘制位图,当然这只是绘制方法之一,而不是唯一的方法。
现在,我来介绍一下什么是透明位图的绘制。 用下面的图像直观地表示吧:
如果有两张照片,一张是背景图:
一张是人物图:
这里,我想把人物画在背景图上,用通常的方法,把人物的照片直接显示在背景图上就可以了。 效果如下。
你可能会看到一些问题,但我们实际上想要的是下一张照片的效果:
是的。 透明位图的绘制类似于上图所示。 只画照片的特定地方,形状不规则,其他不画。 在上面的示例中,将人物挖出来绘制,而不绘制背景的蓝色,即背景看起来透明,所以这是位图的透明绘制。
编程的实现原理
时,TransparentBlt函数的最后一个参数指定黑色RGB(0、0、0 )以外的透明颜色。 透明颜色是指如果指定了RGB值,则不使用Transparent函数绘制,而只绘制其他未指定透明颜色的RGB值的颜色。
在上面的示例中,如果将透明RGB指定为蓝色(0,0,255 ),则只能绘制非蓝色部分的人物图像。
相对而言,为什么指定透明色才能进行透明处理,其本质原理可以参考我写的《使用BitBlt函数实现绘制透明位图》和《使用StretchBlt函数实现绘制透明位图》两篇文章中的透明原理分析。 Transparent函数的实现必须通过调用StretchBlt函数来实现。
编码实现
导入库文件#include
#pragmacomment(lib、' Msimg32.lib ' () ) ) ) ) ) ) 652
绘制背景位图boolpaintbmp(hwndhwnd )
{
//获取窗口客户区域的显示设备上下文环境的句柄
HDCHDC=:3360getdc(hwnd );
创建与//HDC兼容的内存设备上下文环境
hdc hbuf=:3360创建兼容的DC (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);
returnTRUE;
}
绘制透明位图BOOLPaintTransparentBmp(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);
returnTRUE;
}
程序测试
调用上述封装好的函数,直接测试。人物位图成功背景透明绘制到背景图上。而且,人物还能成功拉伸绘制。
总结
使用 TransparentBlt 函数实现透明位图处理,应该是这三种实现方法中最为简单,也是最容易理解的。而且,使用起来还比较简洁灵活。