第12章 GDI+基础编程
GDI+(Graphics Device Interface Plus,图形设备接口加)是Windows XP及以上版本操作系统的图形子系统,也是传统.NET框架的重要组成部分和窗体绘图的主要工具,负责在屏幕和打印机上绘制图形与图像并显示文本信息。顾名思义,GDI+是Windows传统图形设备接口GDI的后续版本,是建立在GDI之上的一个高层图形子系统。
GDI+是一种API,分别通过一套C++类和一套部署为托管代码的类来展现,这两套类分别被称为GDI+的“C++封装”和“托管类接口”。
GDI+不但在功能上比GDI要强大很多,而且在代码编写方面也更简单,因此会成为Windows图形图像程序开发的主要工具之一。由于篇幅所限,本书只简单介绍利用MFC进行GDI+编程的一些基本内容,不讲GDI+的API编程。基于GDI+托管封装的.NET窗体绘图,将在后面的第18章中介绍。对GDI+编程有兴趣的读者,还可以参考如下两本图书:
? 周鸣杨、赵景亮. 精通GDI+编程. 清华大学出版社,2004年2月(C++ / MFC)。 ? Mahesh Chand(韩江等译). GDI+图形程序设计. 电子工业出版社,2005年3月(C# / .NET)。
本章将介绍GDI+的结构和组成,讨论GDI+的几个主要新增特性与功能,说明GDI+给Windows图形图像程序的开发模式带来的变化。介绍C++封装的GDI+ API的具体使用方法,主要讲解二维矢量图形绘制和文字显示等基本内容。
GDI+的路径、区域、变换、图像处理和图元文件等高级编程内容,安排在下一章介绍。
12.1 GDI+的结构与组成
本节先介绍GDI+的体系结构,再列出C++封装的GDI+ API的具体组成。
12.1.1 GDI+的结构
GDI+是建立在GDI之上的一种高层图形子系统,基础是GDI+平面API,有C++和托管两种封装。
注意,虽然GDI+是GDI的发展,但是GDI+并非设计来替代GDI的,它不能独立工作,底层还得靠GDI来实现。
1
1.GDI+的体系结构
GDI+与GDI一样,都具有设备无关性。而且GDI+是建立在GDI之上的一种高层接口,供Windows API和.NET框架调用。与GDI类似,GDI+主要提供了二维矢量图形、图像处理和文字显示版式三类功能(参见图12-1),只是GDI+比GDI的功能更强大,且编程模式发生了很大改变。
.NET框架 GDI+引擎 图像 GDI 设备驱动程序 计算机硬件 图12-1 GDI+的体系结构
Win32/64 (C++) 二维矢量图形 文字 2.GDI+平面API与封装
GDI+提供(expose)了一个平面(flat)API,它包含大约600个函数,被实现在Gdiplus.dll中,声明在Gdiplusflat.h内。这些函数被封装进了GDI+ API的54个C++类的集合之中。
作为C++封装的替代方案,微软.NET框架提供了GDI+的一个托管代码封装类集,包含大约60个类、50个枚举和8个结构。它们分属于下列命名空间:System.Drawing、System.Drawing.Drawing2D、System.Drawing.Imaging、System.Drawing.Text和System. Drawing.Printing。
GDI+的平面API与其C++及托管封装的关系如图12-2所示。
12.1.2 GDI+的组成
GDI+的C++封装,包含了54个类、12个全局函数、(6类)226个图像常量、55种枚举和19种结构。GDI+的.NET托管封装,则包含了大约60个类、50个枚举和8个结构。这两种封装都是基于GDI+平面API的。本小节只介绍GDI+的C++封装,GDI+的托管封装将在第18章的.NET窗体绘图中有所涉及。
2
C++ afxwin.h GDI类与结构 C++封装 (MFC) Gdiplus.h C++封装 GdiplusFlat.h WinGDI.h GDI API 设备驱动程序 Gdiplus GDI+ API C#、VB、C++/CLI、F# System.Drawing[.dll] GDI+托管类接口 DllExports GDI+平面API 托管代码封装 Gdiplus.dll Gdi32.dll 计算机硬件(显示器、打印机等图形设备) 图12-2 GDI+的封装与使用
1.类
GDI+的C++封装中共有54个类,核心类是Graphics,它是实际绘制直线、曲线、图形、图像和文本的类。许多其它GDI+类是与Graphics类一起使用的。例如,Graphics类的DrawLine方法接收Pen对象,该对象中存有所要绘制的线条的属性(颜色、宽度、虚线线型等)。Graphics类的FillRectangle方法可以接收指向LinearGradientBrush对象的指针,该对象与Graphics对象配合工作来用一种渐变色填充矩形。Font和StringFormat对象影响Graphics对象绘制文本的方式。Matrix对象存储并操作Graphics对象的仿射变换——旋转、缩放和翻转图像。
GDI+还提供了用于组织图形数据的几种结构类(例如Rect、Point和Size)。而且,某些类的主要作用是结构化数据类型。例如,BitmapData类是Bitmap类的帮助器,PathData类是GraphicsPath类的帮助器。图12-3是GDI+ API类的层次结构图。
注意:在GDI+、.NET、C#、Java和VB中,都把类的成员函数称为方法。当我们在C++中,使用GDI+和.NET框架类库中的类和功能时,也常常将其成员函数改称为方法。另外,GDI+中的类名不再像MFC那样以字母C开头。
GDI+命名空间中的全局函数有12个,常用的有如下两个(其余的大多数与图像相关): ? 启动GDI+:GdiplusStartup(初始化GDI+)。
? 关闭GDI+:GdiplusShutdown(清除GDI+所使用的资源)。
3
绘图类 GdiplusBase Graphics GraphicsPath GraphicsPathIterator Pen CustomLineCap AdjustableArrowCap Brush SolidBrush HatchBrush TextureBrush LinearGradientBrush PathGradientBrush Image Bitmap Metafile CachedBitmap ImageAttributes Font FontFamily FontCollection InstalledFontCollection PrivateFontCollection StringFormat Region Matrix 独立类 Point Color Size Rect PointF SizeF RectF ImageItemData BitmapData MetafileHeader PropertyItem EncoderParameter EncoderParameters ImageCodecInfo CharacterRange PathData Effect Blur BrightnessContrast ColorBalance ColorCurve ColorLUT ColorMatrixEffect HueSaturationLightness Levels RedEyeCorrection Sharpen Tint 效果类 图12-3 GDI+类的层次结构
3.常量、枚举和结构
GDI+中有6类共计226个图像常量(都被定义在头文件GdiplusImaging.h中),包括图像文件格式常量11个(如ImageFormatBMP、ImageFormatGIF、ImageFormatJPEG、ImageFormatPNG、ImageFormatTIFF等)、图像帧维常量2个、图像编码器常量13个、图像像素格式常量14个、图像特性标志类型9个、图像特性标志217个。
4
2.全局函数
GDI+定义了55种枚举类型,它们都是相关常数的集合。例如:PenType、BrushType、DashStyle、ImageType、LineCap、FillMode、ImageFlags等。
GDI+ API中还定义了19种结构,用于GDI+的各种方法调用中。例如:ColorMap、ColorMatrix、ColorPalette、GdiplusAbort、GdiplusStartupInput、GdiplusStartupOutput等。
12.2 GDI+的特色
本节介绍GDI+的几个主要新增特性与功能,并说明GDI+在编程模式上的改变。
12.2.1 GDI+新增特性
与GDI相比,GDI+新增的特性主要有渐变画刷、样条和贝塞尔曲线、持久路径、矩阵变换、伸缩区域、α混色和对多种图像格式的支持。
1.渐变画刷
GDI+中新增加的渐变画刷(gradient brush,梯度刷),通过提供用于填充图形、路径和区域的颜色线性渐变和路径渐变的画刷,扩展了GDI的功能。渐变画刷可用于绘制直线、曲线和路径,参见图12-4。
a)(水平)线性渐变 b)(贝塞尔)路径渐变
图12-4 渐变画刷
图12-5 基样条曲线与折线
2.曲线方法
GDI+支持基样条(cardinal splines)和贝塞尔(Bezier)曲线算法,可以由若干控制点生成光滑的曲线,参见图12-5。
5