
【visual c++】游戏开发笔记十四 游戏画面绘图(四) 华丽的cimage类.doc
11页【Visual C++】游戏开发笔记十四 游戏画面绘图(四) 华丽的 CImage 类本系列文章由 zhmxy555 编写,转载请注明出处 邮箱: happylifemxy@.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 "atlimage.h"由于 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. #include "atlimage.h" 2. CImage image; //定义一个 CBitmap 类 3. image.Load(“filename”); //filename 为要加载的文件地址 4. HBITMAP hBitmap=image.Detach(); //返回被分离的图片的句柄 5. CBitmap bmp; // 定义一个 bitmap 6. 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 类用于贴图的一般的使用方法使用方法不唯一,最常用的方法如下,该方法大致分为三部分:在源文件中添加 CImage 类的包含文件: #include "atlimage.h"定义一个 CImage 类对象,然后调用 CImage::Load 方法装载一个外部图像文件Load 方法有如下两种重载:[cpp] view plaincopyprint?1. HRESULT Load( 2. LPCTSTR pszFileName //包含加载文件名的字符串指针 3. ) throw( ); 4. 5. 6. HRESULT Load( 7. IStream* pStream //指向包含加载文件名的流的指针 8. ) throw(); 调用 CImage::Draw 方法绘制图像。
下面重点介绍一下 Draw 方法CImage::Draw 将一个位图文件从源设备描述表复制到当前设备描述表该函数有如下六种重载:[cpp] view plaincopyprint?1. BOOL Draw( 2. HDC hDestDC, //目标设备环境 DC 的句柄 3. int xDest, //目的矩形的左上角 X 坐标(逻辑单位) 4. int yDest, //目的矩形的左上角 Y 坐标(逻辑单位) 5. int nDestWidth, //目标矩形的宽度(就是设定贴过去的图片的宽度) 6. int nDestHeight, //目标矩形的高度(就是设定铁锅的图片的高度) 7. int xSrc, //源矩形的左上角 X 坐标 8. int ySrc, //源矩形的左上角 Y 坐标 9. 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 类的所有类函数按功能分为了四大类,可以更方面的了解各函数的定位和作用,也方便大家查阅:功能为创建与连接,释放的函数Attach 附加一个 HBITMAP 到 CImage 对象,位图类型 DIB 与否都可以Create 创建一个 DIB 部分的位图,并将其附加到之前创建的 CImage 对象CreateEX 创建一个 DIB 部分的位图(拥有额外的参数),并将其附加到之前 创建的 CImage 对象Destroy 从 CImage 类上分离该位图并进行删除Detach 从 CImage 类里分离该位图ReleaseDC 释放设备描述表中的数据ReleaseGDIPlus 释放 GDI+使用的源功能为输入与输出的函数GetExporterFilterString 返回系统支持的输入文件格式类型及其描述GetImporterFilterString 返回系统支持的输出文件格式类型及其描述LoadFromResource 从指定的源处加载一个图像资源Load 。
