一、 GDI+三问
1.1 GDI+是什么?
GDI+是GDI(Graphics Device Interface)的后继者,是一种图形设备的接口,它构成了Win XP操作系统的子系统的API。
1.2 GDI+能做什么?
GDI+能够在绘图界面上绘制我们想要的图形。如:对数据进行统计后得到的柱状图或曲线图等。
绘图界面:一般来说有3中基本的用于绘图的界面,分行别是Windows窗体上的控件、要发给打印机的界面和内存中的位图和图像。
1.3 怎么做呢?
在GDI+中我们可以把它分为两种,一种是绘图界面,另一种则是构造块,绘图界面即为上面所说的容器,那构造块呢?程序开发过程中,GDI+中的一些基本构造块可用于绘制二维图形,GDI+支持的基本构造块有:直线、矩形、椭圆、弧线、多边形、基数样条和贝塞尔样条等。
1.3.1 如何绘图:Graphics类
Graphics类封装了一个GDI+绘图界面,该类提供了可以在以上3种绘图界面上绘图的功能,开发人员可以使用该类来绘制文本、线条、矩形、曲线、多边形、椭圆、圆弧和贝塞尔样条等。
Graphics类提供了绘制基本构造块的各种方法,包括DrawLine、DrawRectangle、DrawEllipse、DrawPolygon、DrawArc、DrawCurve(针对基数样条)和DrawBezier等。这些方法中的每一种都可以重载。例如,DrawLine方法的一种形式接收一个Pen对象和4个整数,而它的另一种形式则接收一个Pen对象和两个Point对象。
Graphics类的所有绘制方法都应与Pen对象一起使用。若要进行图形绘制,至少必须创建两个对象:Graphics对象和Pen对象。
另外,绘制直线、矩形和贝塞尔样条的方法具有多个伴随方法,可在一个调用中绘制如下项:DrawLines、DrawRectangles和DrawBeziers。DrawCurve方法也有一个伴随方法DrawClosedCurve,该伴随方法能够通过连接曲线起点和终点的方式来闭合曲线。
二、实例详解
2.1 区域剪辑与填充
上篇中对GDI+基本的概念详述了一遍,通过GDI+能够绘制二维图像,并说到了能够绘制基本构造块的Graphics方法。该篇将会从上篇基础上更深入的讨论GDI+的基本用法,并通过实例来了解Region、GraphicsPath和Brush的使用。
下面的示例分别在窗体上绘制了两个图形,图形1为区域截取即指定了绘图区域的大小,并使用SetClip方法来组合剪辑区域;图形2为矩形填充区域,使用红色作为边界,并使用蓝色填充矩形内部。
/// <summary> /// 剪辑区域绘制事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Graphics g = this.CreateGraphics(); //创建一个绘图界面 //创建一个绘图区域,并将绘图区域与图形路径进行拼合,实现图形区域截取 Point[] p = { new Point(50, 50), new Point(150, 30), new Point(150, 150), new Point(60, 150) }; //创建坐标点数组用来指定所绘制的图形四周的顶点坐标 GraphicsPath gp = new GraphicsPath(); // 创建一个图形路径,用来指定所绘制的图形 gp.AddPolygon(p); //在此路径中添加所画的多边形 Region r = new Region(new Rectangle(new Point(50, 50), new Size(200, 200))); //创建一个绘图区域 r.Intersect(gp); //将指定的区域更新为r和gp的交集 Pen mypen = new Pen(Color.Blue, 3); //创建一个Pen对象 g.DrawPath(mypen, gp); //在g中绘制所创建的路径gp g.SetClip(r, CombineMode.Replace); //组合剪辑区域r //使用DrawString方法在绘图界面上绘制字符串为“GDI+区域” g.DrawString("GDI+区域", new Font(new FontFamily("宋体"), 36, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Red), new PointF(50, 60)); } /// <summary> /// 填充矩形绘制事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { Graphics g = this.CreateGraphics(); //创建一个图形绘制界面 Rectangle rec = new Rectangle(200, 30, 200, 200); //创建一个矩形绘制区域 g.DrawRectangle(new Pen(Color.Red, 2), rec); //绘制该矩形区域的四边 g.FillRectangle(new SolidBrush(Color.Blue), rec); //只用指定的颜色填充矩形区域 }
上面两种绘图本质上是相同的,首先创建一个绘图界面,然后创建绘图区域,其次在绘图界面中获取绘图区域,最后绘制区域。
图形2的绘制很简单,来看看图形1的绘制。对于图形1绘制的区域是路径区域,使用了GraphicsPath只要为它指定了相应的坐标点后,就能够画出任意形状的多边形,最终的功劳应该归功于AddPolygon方法,该方法实现了任意多边形的绘制。其次使用Region类来创建剪辑区域,创建剪辑后需要把该区域与需要被剪辑的区域组合,于是使用了Graphics的SetClip方法实现了两个绘图区域的剪辑组合。
2.2 圆角矩形
上例从基本的图形绘制出发,绘制了两种图形,只要能熟练使用这几种类就能够很快的绘制出想要的图形。接下来看一个圆角矩形的绘制过程。
清单1:封装画法的圆角矩形类。该类封装了具体的圆角矩形的画法,大致的思路是首先分别绘制出矩形的四个圆角,然后使用CloseFigure方法,闭合该区域。当然绘制方法还有很多种,可以自己去研究。
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; namespace Draw { public class RoundRectangle { /// <summary> /// 封装的圆角矩形画法 /// </summary> /// <param name="g">传引用:图形界面对象</param> /// <param name="rect">传引用:图形绘制的区域大小</param> /// <param name="wid">圆角半径值</param> /// <param name="p">圆角矩形的边框的样式</param> /// <param name="sb">圆角矩形内部填充样式</param> public void DrawRoundRectanle(ref Graphics g,ref Rectangle rect,int wid,Pen p,SolidBrush sb) { GraphicsPath gp = new GraphicsPath(); //创建一个图形绘制路径 gp.AddArc(rect.X, rect.Y, wid * 2, wid * 2, 180, 90); //绘制左上圆角 gp.AddArc(rect.X + rect.Width - wid * 2, rect.Y, wid * 2, wid * 2, 270, 90); //绘制右上圆角 gp.AddArc(rect.X + rect.Width - wid * 2, rect.Y + rect.Height - wid * 2, wid * 2, wid * 2, 0, 90); //绘制右下圆角 gp.AddArc(rect.X, rect.Y + rect.Height - wid * 2, wid * 2, wid * 2, 90, 90); //绘制左下圆角 gp.CloseFigure(); //闭合圆角区域,成为一个闭合图形 g.SmoothingMode = SmoothingMode.AntiAlias; //边框消除锯齿 g.DrawPath(p, gp); //绘制路径 g.FillPath(sb, gp); //填充圆角矩形内部 } } }
清单2:圆角矩形绘制事件。单击按钮后绘制出想要的大小的圆角矩形。
/// <summary> /// 剪辑区域绘制事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Graphics g =this.panel1.CreateGraphics(); //创建一个绘图界面 RoundRectangle rr = new RoundRectangle(); //创建圆角矩形绘制对象 int wid = 10; //确定圆角半径 //创建绘制区域 Rectangle rect=new Rectangle (new Point (panel1 .Location .X ,panel1 .Location .Y ),new Size (200,200)); //创建边框和填充样式 Pen p=new Pen (Color .FromArgb (106,154,193),2); SolidBrush sb = new SolidBrush(Color.FromArgb(106, 154, 193)); //绘制区域 rr.DrawRoundRectanle (ref g,ref rect,wid,p,sb); }
三、结语
GDI+图形图像的绘制其实是在封装了底层API后展示给开发人员的一个接口,这是利用了.NET平台的特性,绘制的方法比较简单,主要是几个类的使用,另外想要绘制出想要的图形界面必须对绘制的图形进行计算。同时利用GDI+也可以绘制出数据统计图,只要知道了绘制方法,它会比MSChart控件灵活的多,至于画法将会在接下来的文章中陆续更新。