第10章GDI+图形图像程序设计学习要点1.掌握C#的GDI+常用绘图功能的实现方法2.掌握C#的GDI+文本的字体设置及其呈现的实现方法3.掌握C#的GDI+图像处理的基础知识及动画设计方法4.了解C#的GDI+图像的变形功能的实现方法10.1GDI+概述GDI(GraphicsDeviceInterface,即图形设备接口)是WindowsAPI(ApplicationProgrammingInterface)的一个重要组成部分。而GDI+(GraphicsDeviceInterfacePlus,即增强型图形设备接口)则是GDI的升级版本,是微软在Windows2000以后的操作系统中提供的新的图形设备接口,它在GDI的基础上作了大量的优化、改进。一方面,GDI+提供一些新的功能(如,渐变画刷GradientBrushes以及混合AlphaBlending等),使得GDI的功能得到进一步的扩展;另一方面,GDI+修订了编程模式,使得图形硬件和应用程序相互隔离,也使开发人员编写设备无关的应用程序变得更加容易。GDI+的体系结构如下图所示。Microsoft.NET框架Win32(C++)二维矢量图形图像文本GDI+GDLDirectX系统底层驱动程序GDL+引擎GDI+的体系结构10.1.1.NET图形图像处理命名空间.NET的所有图形图像处理功能都包含在以下命名空间中:•System.Drawing命名空间提供了对GDI+基本图形功能的访问,主要有Graphics类、Bitmap类以及从Brush类继承来的Font类、Icon类、Image类、Pen类和Color类等。•System.Drawing.Drawing2D命名空间提供高级的二维和矢量图形功能。此命名空间包含渐变画笔、Matrix类(用于定义几何变换)和GraphicsPath类。•System.Drawing.Imaging命名空间提供高级GDI+图像处理功能。•System.Drawing.Text命名空间提供高级GDI+字体和文本排版功能。10.1.2GDI+绘图的基本步骤GDI+类及结构形象化类比GraphicsColor,FontPoint,Size,RectanglePen,BrushDrawX(X包括:Line,Polygon等);FillY(Y包括:Line,Polygon等)图形、文本10.1.3Graphics类1.在窗体或控件的Paint事件中直接引用Graphics对象每个窗体或控件都有一个Paint事件,该事件参数中包含了当前窗体或控件的Graphics对象,在为窗体或控件编写绘图代码时,一般使用此方法来获取图形对象的引用。例如:privatevoidForm1_Paint(objectsender,PaintEventArgse){Graphicsg=e.Graphics;//其他图形图像处理代码……}2.调用当前窗体或控件的CreateGraphics方法调用当前窗体或控件的CreateGraphics方法以获取对Graphics对象的引用,该对象表示当前窗体或控件的绘图图面。如果想在已存在的窗体或控件上绘图,可以使用这种方法。例如:Graphicsg=this.CreateGraphics();//其他图形图像处理代码……10.1.3Graphics类3.调用Graphics类的FromImage静态方法调用Graphics类的FromImage静态方法,从继承自图像的任何对象创建Graphics对象,此方法通常用于更改已存在的图像。例如:Bitmapbitmap=newBitmap(@C:\CProgame\b1.bmp);Graphicsg=Graphics.FromImage(bitmap);或者:Imageimg=Image.FromFile(g1.gif);Graphicsg=Graphics.FromImage(img);提示:由于图像对象非常占用系统资源,所以当不再使用这些对象时,应该使用Dispose方法及时将其占用的资源释放掉,以免影响系统的性能。10.1.4颜色颜色是进行图形操作的基本要素。任何一种颜色的表现效果都可以由3个色彩分量和1个透明度参数来确定,每个分量占1B,即:R:红色,取值范围为0~255,255为饱和红色。G:绿色,取值范围为0~255,255为饱和绿色。B:蓝色,取值范围为0~255,255为饱和蓝色。A:即Alpha值,表示一种颜色的透明度,取值范围为0~255,0为完全透明,255为完全不透明。在GDI+中,颜色封装在Color结构中,可用以下几种方法创建颜色对象。10.1.5坐标系统“画布”有了,“颜料”也准备好了,这时似乎可以“执笔”了。其实不然,因为还需先运筹一下“在哪里”下笔和“在什么范围”下笔的问题。这对GDI+来说,就是坐标系统的确定问题。GDI+使用Point、Size和Rectangle结构来进行绘图时的坐标定位和尺寸确定。Point结构GDI+的Point表示一个二维平面上的点,可以使用一些公共属性获取或设置Point的X和Y坐标。声明和构造Point的示例代码如下:Pointp=newPoint(85,100);Size结构GDI+使用Size表示一个尺寸(单位:像素),Size结构包含宽度和高度两个量。可以使用一些公共属性获取或设置Point的X和Y坐标。声明和构造Point的示例代码如下:Sizes=newSize(50,80);Rectangle结构Rectangle可以采用两种构造函数,一种是指定矩形左上角的X和Y坐标以及矩形的宽和高,示例代码如下:Rectanglerct=newRectangle(10,20,150,300);10.1.6画笔与画刷•笔(Pen)笔是Pen类的实例,用于绘制线条或空心图形。通过笔的With属性可以设置其宽度;Color属性可以设置其颜色;StartCap和EndCap属性设置其起点或终点的样式;DashStyle属性则可以设置其线样式,如实线、虚线或点划线等。实例化笔对象的示例代码如下://1个像素宽的红色笔Penpen1=newPen(Color.Red);//5个像素宽的黑色笔Penpen2=newPen(Color.Black,5);另外,也可以从画刷(详见画刷介绍)对象实例化笔,示例代码如下://1个像素宽的红色画刷SolidBrushbrush1=newSolidBrush(Color.Red);//1个像素宽的红色笔Penpen1=newPen(brush1);//5个像素宽的红色笔Penpen2=newPen(brush1,5);•画刷(Brush)画刷是从Brush类派生的任何类的实例,可与Graphics对象一起使用来创建实心图形或呈现文本对象。还可以使用画刷填充各种图形,如矩形、椭圆或多边形等。10.2利用画笔或画刷绘制图形10.2.1绘制直线1.先定义一对坐标点,再将其作为起始点和终点进行划线。其构造函数如下:publicvoidDrawLine(Penpen,PointstartPoint,PointendPoint);示例代码如下:privatevoidForm1_Paint(objectsender,PaintEventArgse){Graphicsg=e.Graphics;Penpen=newPen(Color.Black,5);PointstartPoint=newPoint(10,30);PointendPoint=newPoint(200,90);e.Graphics.DrawLine(pen,startPoint,endPoint);}10.2利用画笔或画刷绘制图形2.直接定义一对起点和终点坐标并进行划线。其构造函数如下:publicvoidDrawLine(Penpen,ntx1,intx2,inty1,inty2);则以上示例代码可改写如下:privatevoidForm1_Paint(objectsender,PaintEventArgse){Graphicsg=e.Graphics;Penpen=newPen(Color.Black,5);e.Graphics.DrawLine(pen,10,30,200,90);}10.2利用画笔或画刷绘制图形3.先定义多对坐标点,再将他们作为首尾相连的起点和终点进行划线。其构造函数如下:publicvoidDrawLine(Penpen,Point[]points);示例代码如下:privatevoidForm1_Paint(objectsender,PaintEventArgse){Graphicsg=e.Graphics;Penpen=newPen(Color.Red,2);Point[]points={newPoint(15,20),newPoint(30,120),newPoint(100,180),newPoint(260,50)};e.Graphics.DrawLines(pen,points);}10.2.2绘制多边形由于多边形既有轮廓且封闭,所以,多边形可划分为空心多边形和实心(有填充)多边形两种。C#.NET中与之对应的绘图方法分别:DrawPolygon方法和FillPolygon方法,不过要注意,DrawPolygon方法需使用笔,FillPolygon方法需使用画刷,如此才可分别绘制空心或实心的多边形。示例代码如下:privatevoidForm1_Paint(objectsender,PaintEventArgse){Graphicsg=e.Graphics;Penpen=newPen(Color.Blue,2);Point[]points1={newPoint(90,40),newPoint(40,150),newPoint(140,150)};10.2.2绘制多边形e.Graphics.DrawPolygon(pen,points1);Brushbrush=newSolidBrush(Color.Red);Point[]points2={newPoint(230,40),newPoint(180,150),newPoint(280,150)};e.Graphics.FillPolygon(brush,points2);}10.2.3绘制曲线C#.NET中可以分别使用DrawCurve方法和DrawClosedCurve方法绘制自定义的开口曲线和封闭曲线;还可以使用DrawBezier方法或DrawBeziers方法绘制一段或多段贝塞尔曲线。自定义曲线绘制可用如下两种构造函数。1.使用默认弯曲强度0.5进行绘图。其构造函数如下:publicvoidDrawCurve(Penpen,Point[]points);2.指定弯曲强度进行绘图。其构造函数如下:publicvoidDrawCurve(Penpen,Point[]points,floattension);其中tension指定定弯曲强度,取值范围为0.0f~1.0f,超出范围将产生异常,取值为0时,绘制直线。(示例代码见教材)10.2.4绘制矩形由于矩形也是既有轮廓且封闭,所以,矩形也可划分为空心矩形和实心(有填充)矩形两种。C#.NET中与之对应的绘图方法分别:DrawRectangle方法(或DrawRectangles)和FillRectangle方法(或FillRectangles),不过要注意,轮廓方法需使用笔,填充方法需使用画刷,如此才可分别绘制空心或实心的矩形。绘制空心矩形可用如下三种构造函数。1.利用Rectangle结构确定矩形边界,一次绘制一个矩形。其构造函数如下:publicvoidDrawRectangle(Penpen,Rectanglerect);2.指定矩形宽和高及其左上角坐标。其构造函数如下:publicvoidDrawRectangle(Penpen,intx,inty,intwidth,intheight)