`
yzd
  • 浏览: 1858508 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

【Visual C++】游戏开发笔记十四 游戏画面绘图(四) 华丽的CImage类

 
阅读更多

本系列文章由zhmxy555编写,转载请注明出处。

作者:毛星云邮箱:happylifemxy@qq.com欢迎邮件交流编程心得



我们知道,VisualC++中的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格式的图片。

具体代码如下:

然后就可以用CBitmap进行余下的操作了。


3.CImage额外的一些性质


CImage类对于DIB(device-independentbitmap)设备无关位图文件和非DIB都可以处理。我们可以通过Create函数或者CImage::Load来处理DIB部分,用Attach函数来将非DIB部分附加到一个CImage对象上。

对于以下函数,只支持DIB部分的位图文件,他们是:

GetBitsGetColorTable,GetMaxColorTableEntries,GetPitch,GetPixelAddress,IsIndexed,SetColorTable。


我们可以通过CImage类中的IsDIBSection()函数来帮助我们判断一个位图文件是否为DIB部分,其定义如下:



我们需要注意的是,CImage不能被选到一个新的CDC(classofdevice-context设备描述表的类),CImage会为图像创建自己的HDC(设备描述表DC的句柄)。因为一个HBITMAP只能被选入到一个HDC中一次,也就是说这个与CImage相关的HBITMAP不能被选到一个其他的HDC中。

如果需要一个CDC,我们可以从CImage中获取HDC,然后使用CDC::FromHandle函数。


4.CImage兼容性的说明


在CImage中,有如下兼容性的要求:

只支持WindowsNT4.0以上系统的成员函数:PlgBlt,MaskBlt,AlphaBlend。

只支持Windows2000,98以上系统的成员函数:TransparentBlt,Draw

其实由于目前都是WindowsXP以上的操作系统,这个知识点了解一下就行。



5.CImage类用于贴图的一般的使用方法


使用方法不唯一,最常用的方法如下,该方法大致分为三部分:

<1>在源文件中添加CImage类的包含文件

#include"atlimage.h"

<2>定义一个CImage类对象,然后调用CImage::Load方法装载一个外部图像文件。Load方法有如下两种重载:




<3>调用CImage::Draw方法绘制图像

下面重点介绍一下Draw方法。

CImage::Draw将一个位图文件从源设备描述表复制到当前设备描述表

该函数有如下六种重载:


在上面的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类上分离该位图并进行删除

Detach从CImage类里分离该位图

ReleaseDC 释放设备描述表中的数据

ReleaseGDIPlus释放GDI+使用的源

<2>功能为输入与输出的函数


GetExporterFilterString返回系统支持的输入文件格式类型及其描述

GetImporterFilterString返回系统支持的输出文件格式类型及其描述

LoadFromResource从指定的源处加载一个图像资源

Load从指定文件处加载一个图像资源

IsIndexed判断一个位图颜色映射到了一个索引调色盘

IsNull判断一个源位图是否被当前载入

Save以指定的类型来保存图像

<3>关于位图类型与参数的函数


GetBits返回一个指向该位图实际像素值指针

GetBPP返回该位图每个像素的位

GetColorTable返回颜色表中RGB值的范围条目

GetDC返回目前被选择的设备描述表

GetExporterFilterString返回系统支持的输入文件格式类型及其描述

GetImporterFilterString返回系统支持的输出文件格式类型及其描述

GetHeight返回当前图像的像素高度

GetMaxColorTableEntries返回颜色表条目中的最大值

GetPitch返回当前图片的间距(单位为字节),用来决定像素格式的

GetTransparentColor返回颜色表中透明色的位置

GetWidth返回当前图片的宽度(单位为像素)

<4>功能为图形绘制与位图块传输相关的函数


AlphaBlend显示一个半透明或者透明像素的位图

BitBlt从源设备描述表复制一个位图文件到当前设备描述表

Draw从源矩形复制一个位图到目的矩形,该函数伸缩或者拉伸位图来适应目标矩 形的尺寸,如果有必要,会处理Alpha值和透明颜色。

MaskBlt用指定的掩码和光栅操作来结合颜色数据和目的位图

PlgBlt执行一个从源设备描述表的矩形到目标设备描述表的平行 四边形的块状位图转换

SetColorTabel在DIB的颜色表中设定一系列条目的RGB颜色的值

SetPixelIndexed设置在指定坐标处的像素(使用索调色板的索引值)。

SetPixelRGB设置在指定坐标处的像素(使用RGB值)

SetPixel在指定坐标处设置像素的颜色

SetTransparentColor设置将被视为透明色的颜色的索引值(只能选取调色板中的 一种颜色)

StretchBlt从源矩形复制一个位图到目的矩形,如果有必要,该函数会 伸缩或者拉伸位图来适应目标矩形的尺寸,

TransparentBlt从源设备描述表中复制一个带有透明色的位图到当前设备 描述表





二,实例运用部分


运用CImage完成透明贴图的一个完整实例

介绍了这么多了,下面我们依然用一个实例来巩固本节笔记的知识。

我们知道,CImage支持透明PNG的贴图,下面我们就运用透明PNG的贴图,来代替之前的掩码操作贴图。

<第一步>

准备两张素材图,一张背景图,一张需要进行透明操作的人物图。

这次的选材就很广了,没有之前透明操作需要自己一定的美工功底或者美工童鞋支持的诸多限制了。

我选的两张图片素材如下:

背景图bg.bmp640x444



人物图onion.bmp130x130(呵呵,可爱的洋葱头~~)


<第二步>

将人物图onion.bmp用photoshop等图像处理软件进行抠图操作,除去红黄相间的背景图,并将背景图用透明图层代替,再将图片大小调节成85x113,用png格式输出,效果如下:

处理好的人物图onion.png85x113


<第三步>

将bg.bmp以及onion.png放到工程目录下,并在源文件写入代码并运行。


该代码和笔记六中代码的思路基本相同,只不过,将笔记六中使用掩码操作进行透明化处理的方式换成了png透明贴图的方式,更加的直观和易懂易用。




详细注释的源代码如下




最后得到的效果图如下:



我们可以改变CImage::Draw函数的参数值,让“洋葱头”出现在地图不同的地方。





通过这个实例可以发现,用CImage类进行透明贴图,实在是方便多了。




本节笔记到这里就结束了,由于近期在做一个纯flash的网站,更新速度和评论的回复都不像往常那么及时,希望大家能够体谅。


本节笔记的源代码请点击这里下载: 【Visual C++】Code_Note_14


感谢一直支持【VisualC++】游戏开发笔记系列专栏的朋友们,也请大家继续关注我的专栏,我一有时间就会把自己的学习心得,觉得比较好的知识点写出来和大家一起分享。

精通游戏开发的路还很长很长,非常希望能和大家一起交流,共同学习,共同进步。

大家看过后觉得值得一看的话,可以顶一下这篇文章,你们的支持是我继续写下去的动力~

如果文章中有什么疏漏的地方,也请大家指正。也希望大家可以多留言来和我探讨编程相关的问题。

最后,谢谢你们一直的支持~~~


——————————浅墨于2012年4月3日


Theend.


分享到:
评论

相关推荐

    【Visual C++】游戏开发笔记之四——游戏画面绘图(一)基本图形绘制-附件资源

    【Visual C++】游戏开发笔记之四——游戏画面绘图(一)基本图形绘制-附件资源

    【Visual C++】游戏开发笔记之六-游戏画面绘图(三)透明特效的制作方法.docx

    【Visual C++ 游戏开发笔记之六——游戏画面绘图(三)透明特效的制作方法】 在游戏开发中,创建具有透明效果的游戏画面是提升游戏视觉质量的关键。在本文中,我们将探讨如何使用Visual C++实现透明特效,特别是...

    【Visual C++】游戏开发笔记之六-游戏画面绘图(三)透明特效的制作方法.pdf

    【Visual C++】游戏开发笔记之六-游戏画面绘图(三)透明特效的制作方法主要探讨了如何在2D游戏中实现透明效果。透明效果在游戏画面中至关重要,它可以使得游戏元素与背景融合,提高视觉体验。在本教程中,作者毛星云...

    【Visual C++】游戏开发笔记4

    【Visual C++】游戏开发笔记4主要探讨了使用GDI(图形设备接口)进行游戏画面绘图的基础知识。GDI是Windows API中的一个重要组件,负责管理所有显像设备的图像显示和输出。本文将深入介绍如何利用GDI进行游戏画面的...

    【Visual C++】游戏开发笔记二十 游戏基础物理建模(二) 重力系统的模拟.docx

    【Visual C++】游戏开发笔记二十 游戏基础物理建模(二) 重力系统的模拟 本篇笔记主要探讨了如何在游戏开发中模拟重力系统,为游戏中的物体运动提供更逼真的效果。作者毛星云通过一个简单的平抛运动示例,解释了如何...

    【Visual C++】游戏编程笔记四:透明动画实现

    在Visual C++环境中,游戏编程涉及许多技术,其中之一就是透明动画的实现。本文将深入探讨如何使用Visual C++来创建具有透明效果的动画,这对于创建复杂的2D或3D游戏场景至关重要。 首先,透明动画的核心在于Alpha...

    【Visual C++】Code_Note_14

    博文的配套源码 《【Visual C++】游戏开发笔记之十四 游戏画面绘图(四) 华丽的CImage类 》 ,原文地址为http://blog.csdn.net/zhmxy555/article/details/7422922, 源码编译环境为vs2010. 我的博客地址是...

    【Visual C++】游戏编程学习笔记五:单一背景滚动

    在游戏开发中,单一背景滚动是一项基础且重要的技术,它为玩家创造了一个动态的游戏环境,使得游戏场景在屏幕上的移动显得更加生动和自然。在【Visual C++】中实现这一功能,可以为初学者提供宝贵的编程经验,同时也...

    Visual C++学习笔记

    ### Visual C++ 学习笔记:动态控件管理与调整 在进行Visual C++应用程序开发时,经常会遇到需要动态创建或调整控件的情况。本文档将详细介绍如何通过使用`EnableWindow`、`ShowWindow`、`MoveWindow`及`...

    【Visual C++】Code_Note_6

    博文的配套源码 《【Visual C++】游戏开发笔记之六——游戏画面绘图(三)透明特效的制作方法》 ,原文地址为http://blog.csdn.net/zhmxy555/article/details/7338082, 源码编译环境为vs2010. 我的博客地址是...

    【Visual C++】Code_Note_5

    博文的配套源码 《【Visual C++】游戏开发笔记之五——游戏画面绘图(二)绘制位图》 ,原文地址为http://blog.csdn.net/zhmxy555/article/details/7335103, 源码编译环境为vs2010. 我的博客地址是...

    fivechess1.rar_visual c

    【标题】"fivechess1.rar" 是一个与Visual C++相关的项目,它包含了一个五子棋游戏的实现。在编程领域,五子棋是一种常见的练习项目,用于学习和掌握基本的游戏逻辑和用户界面设计。 【描述】描述中提到,这个C++...

    C++视频教程-VC深入详解自学笔记(完全免费

    《C++视频教程-VC深入详解自学笔记》是一份全面且免费的学习资源,旨在帮助初学者和有一定基础的开发者深入理解C++编程语言,特别是通过Visual C++ (VC++)这一开发环境进行实践。教程由孙鑫整理,涵盖了从基础到高级...

    002_Visual Studio (gnuplot)显示数组波形.zip

    Visual Studio作为广泛使用的C++开发环境,虽然自身并不具备强大的图形绘制功能,但可以通过与其他软件的集成来实现这一目标。本篇将重点讨论如何利用Visual Studio与gnuplot进行数据可视化,特别是如何显示数组波形...

    VC++技术内幕学习笔记

    本学习笔记主要聚焦于Microsoft Foundation Classes (MFC)的深入理解和应用,MFC是微软为Visual C++开发的一个类库,它为Windows应用程序开发提供了强大的支持。MFC将Windows API封装成易于使用的C++类,使得开发者...

    QT学习笔记(四十多个问题解决方案)

    ### QT学习笔记(四十多个问题解决方案) 在个人学习与使用QT的过程中,遇到了一系列的问题,并针对这些问题找到了相应的解决方案。本文将详细介绍这些解决方案,帮助其他开发者更好地掌握QT开发技巧。 #### 使用`...

Global site tag (gtag.js) - Google Analytics