第6章 GDI+编程 GDI+ 已完全替代 GDI,以图形图像作为对象,可在 Windows 窗体应用程序中以编程方式绘制或操作图形图像。虽然无法对 Web 窗体直接使用 GDI+,但可以通过 Web 服务器的“图像”(Image) 控件显示图形图像。 处理图像图形包括创建 Graphics 对象,使用 Graphics 对象绘制线条和形状、呈现文本或显示与操作图像。
6.1 创建 Graphics 对象 Graphics类是使用GDI+的基础,它代表了所有输出显示的绘图环境,用户可以通过编程操作Graphics 对象,在屏幕上绘制图形、呈现文本或操作图像。 创建Graphics 对象可以有多种方法。 (1) 在为窗体编制 Paint 事件处理程序时,图形对象作为一个 PaintEventArgs 提供。下面的代码引用 Paint 事件的 PaintEventArgs 中的 Graphics 对象: private void Form1_Paint(object sender, System.Windows.Forms.PaintEvent Args pe) { // 声明图形对象并把它设置为PaintEventArgs事件提供的图形对象 Graphics g = pe.Graphics; // 在这插入绘制窗体的代码 } (2) 使用控件或窗体的 CreateGraphics方法来获取对 Graphics 对象的引用,该对象表示这个控件或窗体的绘图表面。例如: Graphics g; // 把g设为一个图形对象,来表示控件或窗体的绘图平面 g = this.CreateGraphics();
6.1 创建 Graphics 对象 (3) 从由 Image 类派生的任何对象创建图形对象,方法是调用 Graphics.FromImage 方法。例如: Bitmap myBitmap = new Bitmap(@"C:\myPic.bmp"); Graphics g = Graphics.FromImage(myBitmap); 在 GDI+ 中,可使用笔对象和画笔对象来呈现图形、文本和图像。笔是 Pen 类的实例,可用于绘制线条和空心形状。画笔是从 MustInherit(抽象)Brush 类派生的任何类的实例,可用于填充形状或绘制文本。Color 对象是表示特定颜色类的实例,笔和画笔可使用它来指示所呈现图形的颜色。例如: // 创建一个红色的笔. Pen myPen = new Pen(Color.Red); // 创建一个深蓝的画刷. SolidBrush myBrush = new SolidBrush(Color.Blue);
6.2 笔 笔可用于绘制线条、曲线以及勾勒形状轮廓。下面的代码创建一支基本的黑色笔: // 创建一个默认宽度为1得黑笔 Pen myPen = new Pen(Color.Black); // 创建一个宽度为5的黑笔 Pen myPen = new Pen(Color.Black, 5); 也可以通过已存在的画笔对象创建笔。下面的代码创建基于已存在画笔(名为 myBrush)的笔: // 创建一个画笔,与myBrush有着相同的属性,并且默认宽度为1。 Pen myPen = new Pen(myBrush); // 创建一个画笔,与myBrush有着相同的属性,并且宽度为5. Pen myPen = new Pen(myBrush, 5); 在创建笔后,即可使用它来绘制线条、弧线或空心形状。
6.2 笔 下面的代码使用笔来绘制椭圆: Pen myPen = new Pen(Color.Black); Graphics g = this.CreateGraphics(); g.DrawEllipse(myPen, 20, 30, 10, 50); 在笔创建后,便可以更改影响笔呈现线条形式的各种属性。Width 和 Color 等属性会影响线条的外观,而 StartCap 和 EndCap 属性预设或自定义的形状添加到线条的开始或结尾。DashStyle 属性使可以在实线、虚线、点划线或自定义点划线之间进行选择,而 DashCap 属性使可以自定义线条中短划线的结尾。
6.3 画笔 画笔是可与 Graphics 对象一起用来创建实心形状和呈现文本的对象。几种不同类型的画笔如表6.1所示。 表6.1 画笔的类型
6.3 画笔 【例6.1】在窗体上绘制一个纯红色的椭圆。该椭圆将符合为其提供的矩形的大小(此例中为表示整个窗体的 ClientRectangle),如图6.1所示。 图6.1 窗体上绘制纯红色的椭圆 代码如下: Graphics g = this.CreateGraphics(); SolidBrush myBrush = new SolidBrush(Color.Red); g.FillEllipse(myBrush, ClientRectangle);
6.4 图案 1.简单图案 HatchBrush可以从大量预设的图案中选择绘制时要使用的图案,而不是纯色。 using System.Drawing.Drawing2D; HatchBrush aHatchBrush = new HatchBrush(HatchStyle.Plaid, Color.Red, Color.Blue); 2.复杂图案 纹理画笔使用图像作为图案填充形状或文本。下面的示例创建一个 TextureBrush,它使用名为 myBitmap 的图像进行绘制。 TextureBrush myBrush = new TextureBrush(new Bitmap(@"C:\myBitmap.bmp")); 3.复杂底纹 渐变画笔支持复杂底纹。使用 LinearGradientBrush,可以创建沿线性渐变的两种颜色平滑、渐进式的混合。PathGradientBrush 支持许多更复杂的底纹和着色选项。
6.4 图案 【例6.2】使用由红色逐渐向黄色混合而形成的渐变, 如图6.2所示。 代码如下: 图6.2 颜色渐变 代码如下: using System.Drawing.Drawing2D Graphics g = this.CreateGraphics(); LinearGradientBrush myBrush = new LinearGradientBrush(ClientRectangle, Color.Red, Color.Yellow, LinearGradientMode.Vertical); g.FillRectangle(myBrush, ClientRectangle);
6.5 颜色 .NET 框架的 Color 结构用于表示不同的颜色。颜色与笔和画笔一起使用来指定要呈现的颜色。 1.系统定义的颜色 Color myColor; myColor = Color.Red; myColor = Color.Aquamarine; myColor = Color.LightGoldenrodYellow; myColor = Color.PapayaWhip; myColor = Color.Tomato; 上面的每个语句均将 myColor 分配给所指示名称的系统定义的颜色。
6.5 颜色 2.用户定义的颜色 可以使用 Color.FromArgb 方法创建用户定义的颜色。定义时可以指定一种颜色中红色、蓝色和绿色各部分的强度。 Color myColor; myColor = Color.FromArgb(23,56,78); 此示例生成一种用户定义的颜色,该颜色大致为略带蓝色的灰色。每个数字均必须是从 0 到 255 之间的一个整数,其中 0 表示没有该颜色,而 255 则为所指定颜色的完整饱和度。因此,Color.FromArgb(0,0,0) 呈现为黑色,而 Color.FromArgb(255,255,255) 呈现为白色。 3.Alpha 混合处理(透明度) Alpha 表示所呈现图形后面的对象透明度。Alpha 混合处理的颜色对于各种底纹和透明度效果很有用。如果需要指定 Alpha 部分,则它应为 Color.FromArgb 方法中四个参数的第一个参数,并且需要从 0 到 255 之间的一个整数。例如: myColor = Color.FromArgb(127, 23, 56, 78); 此示例创建一种颜色,该颜色为略带蓝色的灰色且大致为 50% 透明度。也可以通过指定 Alpha 部分和以前定义的颜色来创建 Alpha 混合处理的颜色。 myColor = Color.FromArgb(128, Color.Tomato); 此示例创建一种颜色,该颜色大约 50% 透明度,为系统定义的Tomato 的颜色。
6.6 绘制线条或空心形状 Graphics 对象提供绘制各种线条和形状的方法。可以用纯色或透明色或使用用户定义的渐变或图像纹理来呈现简单或复杂的形状。可使用 Pen 对象创建线条、非闭合的曲线和轮廓形状。若要填充矩形或闭合曲线等区域,则需要使用Brush 对象。 绘制线条或空心形状的步骤如下: (1) 获取用于绘图的图形对象的引用。例如: Graphics g = Button1.CreateGraphics(); (2) 创建绘制线条的 Pen 类的实例,并设置所有相应的属性。例如: Pen myPen = new Pen(Color.Red); myPen.Width = 5; (3) 调用绘制形状的方法,并提供所有需要的参数。表6.2列出了几个最常用的方法。 表6.2 绘制形状的方法
6.6 绘制线条或空心形状 例如: g.DrawLine(myPen, 1, 1, 45, 65); g.DrawBezier(myPen, 15, 15, 30, 30, 45, 30, 87, 20); g.DrawEllipse(myPen, new Rectangle(33, 45, 40, 50)); g.DrawPolygon(myPen, new PointF[] {new PointF(1, 1), new PointF (20, 10), new PointF(5, 4), new PointF(100, 2), new PointF(200, 50), new PointF(39, 45)}); 运行结果如图6.3所示。 图6.3 运行结果
6.7 绘制实心形状 绘制实心形状步骤如下: (1) 获取绘图的图形对象的引用。例如: Graphics g = Button1.CreateGraphics; (2) 创建绘制形状的 Brush 的实例。例如: SolidBrush myBrush = new SolidBrush(Color.Red); (3) 调用绘制形状的方法,并提供所有相应的参数。对于某些方法(如 FillPolygon),必须提供一系列点,这些点描述要绘制形状的轮廓。而其他方法(如 FillRectangle 或 FillPath)则需要一个描述要填充区域的对象。 示例代码如下: g.FillPolygon(myBrush, new PointF[] {new PointF(20, 20), new PointF(50, 100), new PointF(60, 10), new PointF(200, 4), new PointF(0, 0), new PointF(20, 20)}); g.FillRectangle(myBrush, new RectangleF(50, 50, 100, 100)); g.FillPie(myBrush, new Rectangle(0, 0, 300, 300), 0, 90);
6.7 绘制实心形状 运行结果如图6.4所示。 图6.4 运行结果
6.8 用 GDI+显示字符串 可以使用任何图形对象作为呈现文本的表面。呈现文本需要一个 Brush 对象(它指示将使用什么图案填充文本)和一个 Font 对象(它描述要填充的图案)。字体可以是系统上安装的任何已命名的字体,而画笔可以为任意类型的画笔。因此,有可能使用纯色、图案或者甚至图像来绘制文本。 绘制字符串步骤如下: (1) 获取对将用于绘图的图形对象的引用。例如: // 为Button1获得一个图形对象的引用 Obtains a reference to the Graphics object for Button1 Graphics g = Button1.CreateGraphics(); (2) 创建绘制文本要使用的“画笔”的实例。例如: System.Drawing2D.LinearGradientBrush myBrush = new System.Drawing2D.LinearGradientBrush(ClientRectangle, Color.Red, Color.Yellow, Drawing2D.LinearGradientMode.Horizontal); (3) 创建显示文本要使用的字体。例如: Font myFont = new Font("Times New Roman", 24);
6.8 用 GDI+显示字符串 (4) 调用 Graphics 对象的 Graphics.DrawString 方法来呈现文本。如果提供 RectangleF 对象,则文本将在矩形中换行。否则,文本将从提供的起始坐标处开始。例如: g.DrawString("Look at this text!", myFont, myBrush, new RectangleF(10, 10, 100, 200)); g.DrawString("Look at this text!", myFont, myBrush, 85, 50); 运行结果如图6.5所示: 图6.5 运行结果
6.9 用 GDI+显示图像 可以使用 GDI+ 在应用程序中呈现以文件形式存在的图像。实现此操作的方法是:创建Image 类(如 Bitmap)的一个新对象,创建一个 Graphics 对象(它表示要使用的绘图表面),然后调用 Graphics 对象的 DrawImage 方法。将在图形类所表示的绘图表面上绘制图像。在设计时使用“图像编辑器”创建并编辑图像文件,而在运行时使用 GDI+ 呈现它们。 要呈现图像按以下步骤进行。 (1) 创建一个对象,该对象表示要显示的图像。该对象必须是从 Image(如 Bitmap 或 MetaFile)继承的类的成员。例如: Bitmap myBitmap = new Bitmap("C:\MyImages\TestImage.bmp"); (2) 创建一个 Graphics 对象,该对象表示要使用的绘图表面。例如: // 创建一个图形对象,代表Button1的绘图表面 Graphics g = Button1.CreateGraphics();
6.9 用 GDI+显示图像 (3) 调用图形对象的 Graphics.DrawImage 方法来呈现图像。必须同时指定要绘制的图像以及将绘制它的位置的坐标。例如: g.DrawImage(myBitmap, 1, 1); 运行结果如图6.6所示。 图6.6 运行结果