GDI:Graphics Device Interface,即图形设备接口,是Windows API的一个重要组成部分。它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具体设备的细节,而只需在一个虚拟的环境(即逻辑设备)中进行操作。它的桥梁作用体现在:
(1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。
为实现图形设备无关性,Windows的绘图操作在一个设备描述表上进行。用户拥有自己的“逻辑坐标”系统,它独立于实际的物理设备,与“设备坐标”相对应。开发Windows应用程序时,程序员关心的是逻辑坐标,我们在逻辑坐标系上绘图,利用GDI将逻辑窗口映射到物理设备上。
(2)GDI能检测具体设备的能力,并依据具体的设备以最优方式驱动这些设备,完成真实的显示。
GDI函数大致可分类为:
GDI虽然使程序员得到了一定程度的解脱,但是其编程方式仍很麻烦。譬如,显示一张位图,程序员需要进行“装入位图 | 读取位图文件头信息 | 启用设备场景 | 调色板变换”等一连串操作。而有了GDI+,这些问题便迎刃而解了。
GDI+:GDI+是GDI的后续版本,最早于2001年随WinXP一起推出,后来又被包装进.NET框架的托管类库中,成为.NET中窗体绘图的主要工具。
GDI+主要提供了以下三类服务:
(1)二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;
(2)图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类。它们可用于显示、操作和保存BMP、JPG、GIF等图像。
(3)文字显示:GDI+支持使用各种字体、字号和样式来显示文本。
GDI接口是基于函数的,而GDI+是基于C++ OO的编程接口,因此使用起来比GDI要方便。因为GDI+实际上是GDI的封装和扩展,所以执行效率一般要低于GDI。
使用GDI时,经常需要将PEN、BRUSH等GDI对象选入DC,并需要保存旧的GDI对象,然后进行一些绘图操作。此时调用的绘图函数都是使用这些新选入的PEN、BRUSH,绘图完成之后再把旧的GDI对象重新选回DC,这称之为“状态模式”。而GDI+不是这样,GDI+只是将PEN、BRUSH等对象作为参数传递给绘图函数,它们只影响这一次的绘制,下次再调用绘图函数,可以将新的PEN、BRUSH传入给绘图函数,这称为“无状态模式”。与GDI相比,GDI+的编程模式发生了改变。
1、DC与Graphics
DC是GDI的核心,Graphics对象是GDI+的核心。DC和Graphics对象的作用相似,但使用句柄的编程模式和使用Graphics对象的面向对象的编程模型之间,存在一些基本的差异。
Graphics对象(像DC一样)与屏幕上的特定窗口关联,并具有指定如何绘制项目的属性(如 SmoothingMode 和 TextRenderingHint)。但Graphics 对象不受笔、刷、路径、图像或字体的约束,这与DC不同。例如,使用DC画线之前,必须先调用SelectObject以使笔对象和DC关联,即将笔选入DC中。之后的画线操作均使用该笔,直到选择另一支不同的笔为止。在GDI+中,将Pen对象作为参数传递给Graphics类的DrawLine方法。可以在一系列的 DrawLine 调用中,使用不同的Pen对象,而不必将给定的Pen对象与Graphics对象关联。
2、以画线为例
无论是GDI还是GDI+,都有API和MFC封装类两种使用方式。下面每个示例都从点(20, 10)到点(200, 100)绘制一条宽为3 的红色线条。
(1)GDI API
(2)GDI MFC
(3)GDI+ API
(4)GDI+ MFC
3、方法重载
许多GDI+方法都是重载的,这与MFC封装后的GDI类似。例如,DrawLine的重载方法有:
4、绘制和填充
GDI有一个Rectangle函数,可一步完成绘制轮廓和填充矩形内部。轮廓由当前选定的笔绘制,而内部则由当前选定的刷来填充。 GDI+使用Graphics类的DrawRectangle方法将 Pen对象作为参数绘制轮廓,使用Graphics类FillRectangle方法将Brush对象作为参数填充内部。
5、构造区域
GDI提供几种用于创建区域的函数(在MFC中,被封装在CRng类里):CreateRectRgn、CreateEllpticRgn、CreateRoundRectRgn、CreatePolygonRgn 和CreatePolyPolygonRgn。你或许希望GDI+中的Region类也有类似的构造函数,将矩形、椭圆、圆角矩形和多边形作为参数接收,但事实并非如此。GDI+中的Region类提供一个接收Rectangle 对象的构造函数和另一个接收GraphicsPath对象的构造函数。如果想基于椭圆、圆角矩形或多边形构造区域,可以通过创建一个GraphicsPath对象(可包含椭圆的对象等),然后将其传递至Region构造函数来轻松实现。
路径(path)是一系列相互连接的直线和曲线,由许多不同类型的点所构成,用于表示复杂的不规则图形,也叫做图形路径(graphics path)。路径可以被画轮廓和填充,也可以用于创建区域和路径渐变刷等。在 GDI+中,路径由图形路径类GraphicsPath表示,它也是图形基类GraphicsBase 的派生类。关于GraphicsPath,以后再学习。