发布时间 : 星期日 文章Visual C++游戏开发笔记十四 游戏画面绘图(四) 华丽的CImage类更新完毕开始阅读fc6da568b84ae45c3b358c84
【Visual C++】游戏开发笔记十四 游戏画面绘图(四) 华丽的CImage类
本系列文章由zhmxy555编写,转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/7422922 作者:毛星云 邮箱: happylifemxy@qq.com 欢迎邮件交流编程心得
我们知道,Visual C++中的CBitmap类的功能简直太弱小了,这曾经让Visual C++在图像处理方面的功能比较尴尬。之前笔记里面,我们采用的CBitmap配合GDI进行透明图像的处理有些晦涩繁琐,而且受到图像素材的限制,可以说是有些落后,不是太实用。
为了解决这个问题,这节笔记我们将系统的学习MFC和ATL中新增一个图像处理的类,它就是华丽而强大的CImage类。
由于本节笔记是对CImage类的一个非常系统近乎完全的介绍,我尽量让它涵盖到了CImage类的所有的属性和类成员,所以
篇幅也许比以往的笔记内容都长,里面的不少内容是用到的时候才需要掌握或者查阅的,并不用强行记忆。
一,概念讲解部分
1.CImage类的定位和概述
首先,我们简单介绍一下CImage类的定位。
CImage是MFC和ATL共享的新类,它提供了增强的位图支持,包括加载、保存和转换JPEG,BMP,GIF,PNG图像格式的能力。可以说是微软意识到了CBitmap的不足,然后推出了一个CBitmap的增强版。使用CImage类,需在代码头部加入包含atlimage.h文件,即添加代码#include \。
由于CImage拥有功能强大的类成员函数的支持,它便具有了下列四个比较出彩的特性: 1、AlphaBlend支持像素级的颜色混合,从而实现透明和半透明的效果。
2、PlgBlt能使一个矩形区域的位图映射到一个平行四边形区域中,而且还可能使用位屏蔽操作。 3、TransparentBlt在目标区域中产生透明图像
4、MaskBlt在目标区域中产生源位图与屏蔽位图合成的效果。
2.以CImage类做媒,让CBitmap类也能处理丰富的图片格式
解决的思路比较明朗,我们采用CImage类的Load函数加载图片,之后用Detch取得HBITMAP的句柄,然后再将此句柄附加给CBitmap的对象就行了。
这样就实现了让CBitmap类也可以操作JPG/JPEG/GIF/PNG格式的图片。 具体代码如下:
[cpp] view plaincopyprint?
1. 2. 3. 4. 5. 6.
#include \
CImage image; //定义一个CBitmap类 image.Load(“filename”); //filename为要加载的文件地址 HBITMAP hBitmap=image.Detach(); //返回被分离的图片的句柄 CBitmap bmp; // 定义一个bitmap bmp.Attach(hBitmap); //进行句柄的附加
然后就可以用CBitmap进行余下的操作了。
3.CImage额外的一些性质
CImage类对于DIB(device-independent bitmap)设备无关位图文件和非DIB都可以处理。我们可以通过Create函数或者CImage::Load来处理DIB部分,用Attach函数来将非DIB部分附加到一个CImage对象上。 对于以下函数,只支持DIB部分的位图文件,他们是:
GetBitsGetColorTable,GetMaxColorTableEntries,GetPitch,GetPixelAddress,IsIndexed,SetColorTable。
我们可以通过CImage类中的IsDIBSection()函数来帮助我们判断一个位图文件是否为DIB部分,其定义如下:
[cpp] view plaincopyprint?
1. bool IsDIBSection( ) const throw( ); //如果返回值为true,则该文件为DIB;返回flase则不是DIB文件
我们需要注意的是,CImage不能被选到一个新的CDC( class of device-context设备描述表的类),CImage会为图像创建自己的HDC(设备描述表DC的句柄)。因为一个HBITMAP只能被选入到一个HDC中一次,也就是说这个与CImage相关的HBITMAP不能被选到一个其他的HDC中。
如果需要一个CDC,我们可以从CImage中获取HDC,然后使用CDC::FromHandle函数。
4.CImage兼容性的说明
在CImage中,有如下兼容性的要求:
只支持Windows NT4.0以上系统的成员函数:PlgBlt,MaskBlt,AlphaBlend。 只支持Windows 2000,98以上系统的成员函数:TransparentBlt,Draw
其实由于目前都是Windows XP以上的操作系统,这个知识点了解一下就行。
5.CImage类用于贴图的一般的使用方法
使用方法不唯一,最常用的方法如下,该方法大致分为三部分:
<1> 在源文件中添加CImage类的包含文件:
#include \
<2> 定义一个CImage类对象,然后调用CImage::Load方法装载一个外部图像文件。Load方法有如下两
种重载:
[cpp] view plaincopyprint?
1. 2. 3. 4. 5. 6. 7. 8.
HRESULT Load(
LPCTSTR pszFileName //包含加载文件名的字符串指针 ) throw( );
HRESULT Load(
IStream* pStream //指向包含加载文件名的流的指针 ) throw();
<3> 调用CImage::Draw方法绘制图像。
下面重点介绍一下Draw方法。
CImage::Draw 将一个位图文件从源设备描述表复制到当前设备描述表 该函数有如下六种重载:
[cpp] view plaincopyprint?
1. 2. 3. 4. 5. 6. 7. 8. 9.
BOOL Draw(
HDC hDestDC, //目标设备环境DC的句柄
int xDest, //目的矩形的左上角X坐标(逻辑单位) int yDest, //目的矩形的左上角Y坐标(逻辑单位)
int nDestWidth, //目标矩形的宽度(就是设定贴过去的图片的宽度) int nDestHeight, //目标矩形的高度(就是设定铁锅的图片的高度) int xSrc, //源矩形的左上角X坐标 int ySrc, //源矩形的左上角Y坐标 int nSrcWidth, //源矩形的宽度
10. int nSrcHeight //源矩形的高度 11. ) const throw( ); 12. 13.
14. BOOL Draw(
15. HDC hDestDC, //目标环境DC的句柄
16. const RECT& rectDest, //一个RECT结构的引用,用来确定目标图像。 17. const RECT& rectSrc //一个RECT结构体的引用,用来确定源图像 18. ) const throw( ); 19. 20.
21. BOOL Draw(
22. HDC hDestDC, //目标环境DC的句柄
23. int xDest, //目标矩形的左上角X坐标 24. int yDest //目标矩形的左上角Y坐标 25. ) const throw( ); // 26. BOOL Draw(
27. HDC hDestDC, //目标环境DC的句柄
28. const POINT& pointDest //一个POINT结构体,用来确定目的矩形的左上角坐标 29. ) const throw( ); 30. 31.
32. BOOL Draw(
33. HDC hDestDC, //目标环境DC的句柄 34. int xDest, //目标矩形的左上角X坐标 35. int yDest, //目标矩形的左上角Y坐标 36. int nDestWidth, //目标矩形的宽度 37. int nDestHeight //目标矩形的宽度 38. ) const throw( ); 39. 40.
41. BOOL Draw(
42. HDC hDestDC, //目标环境DC的句柄
43. const RECT& rectDest //一个RECT结构的引用,用来确定目标图像。 44. ) const throw( );
在上面的Draw函数的各种重载中,对于没有指定源矩形的版本,则整个源图像就是默认的源矩形。对于没有指定目的矩形尺寸的,则源图片的尺寸就是默认的目的矩形尺寸。
需要注意的是,Draw方法综合了StretchBlt、TransparentBlt和AlphaBlend函数的功能。。通常情况下,Draw()函数作用和StretchBlt()函数一致。但是当我们的图像中存在透明的颜色和alpha通道的时候,Draw()函数作用和TransparentBlt()或者AlphaBlend()函数一致。所以,在一般情况下,我们都尽量调用Draw方法来绘制图像。
6.对CImage所有类成员的介绍
我将CImage类的所有类函数按功能分为了四大类,可以更方面的了解各函数的定位和作用,也方便大家查阅:
<1>功能为创建与连接,释放的函数
Attach 附加一个HBITMAP到CImage对象,位图类型DIB与否都可以 Create 创建一个DIB部分的位图,并将其附加到之前创建的CImage对象
CreateEX 创建一个DIB部分的位图(拥有额外的参数),并将其附加到之前 创建的CImage对象 Destroy 从CImage类上分离该位图并进行删除