Foooooooood
自己使用VC和VS写过很多小游戏,而且不是用现成的游戏引擎,纯粹是使用GDI函数来进行绘图。所以,积累了一些绘图的经验。
那么,对于位图半透明的绘制,在小游戏中使用也比较多。例如烟雾、光等之类的绘制。在没有了解 AlphaBlend 函数之前,绘制半透明位图都是获取两张图片的RGB数据,然后按指定透明度计算出混合后的RGB的值,再显示出来。这样,需要自己计算的过程,算是麻烦。而现在,AlphaBlend 函数直接封装了这步操作,提供了方便使用的接口。
现在,我们就来介绍使用 AlphaBlend 函数绘制半透明位图,写成文档,分享给大家。
该函数用来显示具有指定透明度的图像。
函数声明
AlphaBlend(
HDC hdcDest,
int nXOriginDest,
int nYOriginDest,
int nWidthDest,
int hHeightDest,
HDC hdcSrc,
int nXOriginSrc,
int nYOriginSrc,
int nWidthSrc,
int nHeightSrc,
BLENDFUNCTION blendFunction
);
参数
hdcDest:指向目标设备环境的句柄。
nXOriginDest:指定目标矩形区域左上角的X轴坐标,按逻辑单位。
nYOriginDest:指定目标矩形区域左上角的Y轴坐标,按逻辑单位。
nWidthDest:指定目标矩形区域的宽度,按逻辑单位。
hHeightdest:指向目标矩形区域的高度,按逻辑单位。
hdcSrc:指向源设备环境的句柄。
nXOriginSrc:指定源矩形区域左上角的X轴坐标,按逻辑单位。
nYOriginSrc:指定源矩形区域左上角的Y轴坐标,按逻辑单位。
nWidthSrc:指定源矩形区域的宽度,按逻辑单位。
nHeightSrc:指定源矩形区域的高度,按逻辑单位。
blendFunction:指定用于源位图和目标位图使用的alpha混合功能,用于整个源位图的全局alpha值和格式信息。最后一个参数blendFunction是一个BLENDFUNCTION结构。
BLENDFUNCTION结构介绍如下:
typedef struct _BLENDFUNCTION {
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, PBLENDFUNCTION, LPBLENDFUNCTION;BlendOp: 这个参数必须也只能为AC_SRC_OVER(0x00),意思就是把源图片覆盖到目标之上。
BlendFlags: 必须为0 。
SourceConstantAlpha: 简写为SCA,指定源图片的透明度,这个值是会和源图片的Alpha通道值合并计算的;即设置透明度,0为完全透明,255为完全不透明 。
AlphaFormat: 可以填两种,一种是0x00,一种是AC_SRC_ALPHA (0x01);0表示常量alpha值,AC_SRC_ALPHA表示每个像素有各自的alpha通道。
返回值
- 如果函数执行成功,那么返回值为TRUE;如果函数执行失败,那么返回值为FALSE。
下面,我们举例说明,什么是透明度绘制。现在,有两张位图,一张是背景图:
另一张是其它图片:
那么,半透明绘制,就是要将两张图片绘制在一起,实现下面的效果:
半透明位图绘制的功能实现,主要是靠 AlphaBlend 函数完成的。AlphaBlend 函数的最后一个参数 BLENDFUNCTION 结构指定用于源位图和目标位图使用的alpha混合功能。
其中,BLENDFUNCTION 结构的 SourceConstantAlpha 变量,指定了源图片的透明度,这个值是会和源图片的 Alpha 通道值合并计算的;即设置透明度,0为完全透明,255为完全不透明 。也就是说,只要我们控制这个变量的值,就控制了位图绘制的透明度。
#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 PaintAlphaBlendBmp(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);
// 设置透明度参数
BLENDFUNCTION ftn = { 0 };
ftn.BlendOp = 0;
ftn.BlendFlags = 0;
ftn.SourceConstantAlpha = 200; // 透明度指定
ftn.AlphaFormat = 0;
// 指定透明度绘制
::AlphaBlend(hDC, 0, 0, 650, 350, hBuf, 0, 0, 650, 350, ftn);
// 还原位图对象
::SelectObject(hBuf, hOldBmp);
// 释放位图
::DeleteObject(hBmp);
// 释放兼容的内存设备上下文环境
::DeleteDC(hBuf);
// 释放设备上下文环境
::ReleaseDC(hWnd, hDC);
return TRUE;
}
调用上述封装好的函数进行测试,两幅位图成功按照指定的透明度混合显示:
这个小程序重点是要理解 AlphaBlend 函数的使用方式,可以自己更改透明度的值尝试几次,加深理解。这个函数同样支持对位图伸缩绘制,使用起来比较灵活。
keyboard_arrow_left上一篇 : 【翻译】基于python-docx实现的解析docx文件,顺序保存文字、表格、图片 编程学习笔记之vector学习心得 : 下一篇keyboard_arrow_right