第14章 GDI+图形图像
本章视频教学录像:42分钟
利用 .NET 框架所提供的 GDI+(Graphics Device Interface Plus)类库,可以很容易地绘制各种图形,包括绘制直线和形状,处理位图图像和各种图像文件,还可以显示各种风格的文字。
本章要点(已掌握的在方框中打钩)
□ 什么是GDI+
□ Graphics 对象
□ Pen 对象
□ Brush 对象
□ Font 结构
□ Color 结构
□ Point 结构
□ 基本图形的绘制
14.1 GDI+概述
本节视频教学录像:3分钟
GDI+是以前版本GDI的后继者,它是一组通过C++类实现的应用程序编程接口,主要负责在显示屏幕和打印设备输出有关信息。GDI+对以前的Windows版本中的GDI进行了优化,并添加了许多新的功能。建议在开发新应用程序的时候,使用GDI+而不是GDI(在满足图形输出需要的前提下)。
GDI+主要提供了以下三类服务:
⑴二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类。
⑵图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。
⑶文字显示:GDI+支持使用各种字体、字号和样式来显示文本。我们要进行图形编程,就必须先讲解Graphics类,同时我们还必须掌握Pen、Brush和Rectangle这几种类。
GDI+比GDI优越主要表现在两个方面。
●通过提供新功能(例如:渐变画笔和alpha混合)扩展了GDI的功能。
●修订了编程模型,使图形编程更加简易灵活。
14.2 GDI+常用绘图对象
本节视频教学录像:16分钟
本节主要介绍GDI+中常用的绘图对象。
14.2.1 创建Graphics对象
一般来说,有3种基本类型的绘图界面,分别为Windows窗体上的控件、要发给打印机的页面和内存中的位图与图像,而Graphic1s类封装了一个GDI+绘图界面,因此该类提供了可以在以上3种绘图界面上绘图的功能。另外,程序开发人员还可以使用该类绘制文本、线条、矩形、曲线、多边形、椭圆、圆弧和贝塞尔样条等。
用户可以通过编程操作Graphics对象,在屏幕上绘制图形,呈现文本或操作图像。创建Graphics对象一般有三种方法:
⑴利用窗体或控件的Paint事件。
⑵使用窗体或控件的CreateGraphics方法,用于对象已经存在的情况下。
⑶使用Graphics的静态方法FromImage(Image image)创建Graphics对象,用于在C#中对图像进行处理的场合。
有了一个Graphics的对象引用后,就可以利用该对象的成员进行各种各样图形的绘制,下表列出了Graphics类的常用方法成员。
【范例14-1】创建Graphics对象。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体并切换到设计视图。
⑵双击页面打开Default.aspx.cs文件,引入命名空间:using System.Drawing;
⑶在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 400, hight= 250;
04 Bitmap bitmap= new Bitmap(width, hight);
05 Graphics g=Graphics.FromImage(bitmap);
06 try
07 {
08 g.Clear(Color.YellowGreen);
09 Pen myPen= new Pen(Color.Blue);
10 g.DrawEllipse(myPen, 50, 60, 80, 80);
11 System.IO.MemoryStream ms= new System.IO.MemoryStream();
12 bitmap.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
13 Response.ClearContent();
14 Response.ContentType= ("image/Gif");
15 Response.BinaryWrite(ms.ToArray());
16 }
17 catch (Exception ms)
18 {
19 Response.Write(ms.Message);
20 }
21 }
【运行结果】
按【Ctrl+F5】组合键运行,如下图所示。
【范例分析】
本范例中,第4~5行创建Graphics对象,第9行创建Pen对象,第10行绘制椭圆,11~15行获取图像的二进制流并输出图像的二进制流。
14.2.2 Pen对象
画笔Pen可用于绘制指定宽度、颜色的直线和曲线。使用画笔时,需要先实例化一个画笔对象,主要有以下几种方法:
1. 用指定的颜色实例化一支画笔
Pen(Color color)
2. 用指定的颜色和宽度实例化一支画笔
Pen(Color color, float width)
3. 用指定的画刷实例化一支画笔
Pen(Brush brush)
4. 用指定的画刷和宽度实例化一支画笔
Pen(Brush brush, float width)
【范例14-2】创建Pen对象。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体并切换到设计视图。
⑵双击页面打开Default.aspx.cs文件,引入命名空间:using System.Drawing;
⑶在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 400, hight= 250;
04 Bitmap bitmap= new Bitmap(width, hight);
05 Graphics g=Graphics.FromImage(bitmap);
06 try
07 {
08 g.Clear(Color.YellowGreen);
09
10 Pen p1= new Pen(Color.Blue);
11 Pen p2= new Pen(Color.Yellow, 10);
12
13 SolidBrush brush1= new SolidBrush(Color.Blue);
14 SolidBrush brush2= new SolidBrush(Color.Yellow);
15 Pen p3= new Pen(brush1);
16 Pen p4= new Pen(brush2, 10);
17
18 g.DrawLine(p1, 10, 10, 200, 10);
19 g.DrawLine(p2, 10, 60, 200, 60);
20 g.DrawLine(p3, 10, 110, 200, 110);
21 g.DrawLine(p4, 10, 160, 200, 160);
22
23 System.IO.MemoryStreamms= new System.IO.MemoryStream();
24 bitmap.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
25 Response.ClearContent();
26 Response.ContentType= ("image/Gif");
27 Response.BinaryWrite(ms.ToArray());
28 }
29 catch (Exception ms)
30 {
31 Response.Write(ms.Message);
32 }
33 }
【运行结果】
按【Ctrl+F5】组合键运行,如下图所示。
【范例分析】
本范例中,第10~11行、15~16行分别创建了Pen对象,第18~21行分别使用创建的Pen对象绘制直线,23~27行获取图像的二进制流并输出图像的二进制流。
14.2.3 Brush对象
画刷与Graphics对象一起使用可以创建实心形状,以及呈现颜色与图案的对象。Brush类是一个抽象的基类,因此它不能被实例化,我们总是用它的派生类进行实例化一个画刷对象。几种不同类型的画刷如下表所示。
【范例14-3】建立Brush派生类对象。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体并切换到设计视图。
⑵双击页面打开Default.aspx.cs文件,引入命名空间:using System.Drawing;
⑶在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 400, hight= 250;
04 Bitmap bitmap= new Bitmap(width, hight);
05 Graphics g=Graphics.FromImage(bitmap);
06 try
07 {
08 g.Clear(Color.YellowGreen);
09 Pen p1= new Pen(Color.Black);
10 g.DrawRectangle(p1, 30, 30, 70, 50);
11 SolidBrush brush1= new SolidBrush(Color.Black);
12 g.FillRectangle(brush1, 130, 30, 70, 50);
13
14 System.IO.MemoryStreamms= new System.IO.MemoryStream();
15 bitmap.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
16 Response.ClearContent();
17 Response.ContentType= ("image/Gif");
18 Response.BinaryWrite(ms.ToArray());
19 }
20 catch (Exception ms)
21 {
22 Response.Write(ms.Message);
23 }
24 }
【运行结果】
按【Ctrl+F5】组合键运行,运行结果如下图所示。
14.2.4 Font结构
Font 定义特定文本格式,包括字体、字号和字形属性。Font 类的常用构造函数是 public Font (string familyName,float emSize,FontStyle style)和public Font(string familyName,float emSize),其中“familyName”为Font的FontFamily的字符串表示形式。emSize指示字体尺寸。字体尺寸用来指定字符所占区域的大小,通常用字符的高度来描述。字体尺寸可以用毫米或尺寸作为单位,但为了直观起见,也常常采用一种称为点的单位。在某些场合,点又称为磅。GDI+为用户提供了Display(1/75英寸)、Pixel(像素)、Point(点)、Inch(英寸)、Document(1/300英寸)、Millimeter(毫米)等字体尺寸单位。FontStyle枚举定义了字体的风格:Regular(正常)、Bold(加粗)、Italic(斜体)、Underline(带下划线)和Strikeout(带删除线)。用户可以指定字体使用其中的某种风格,也可以使用“|”运算符为字体指定复合的风格。使用字体族FontFamily类可以获取一些字体在设计时的有用信息,如字形的详细规格。
FontFamily fontFamily = new FontFamily("Arial");
Font font = new Font(fontFamily,16,FontStyle.Regular);
FontFamily类的常用成员和属性如下表所示。
字体常用属性如下表所示。
【范例14-4】创建一个ASP.NET 网站,运行之后在浏览器中显示两条不同字体的字符串。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image控件。
⑶双击页面打开Default.aspx.cs文件,引入命名空间using System.Drawing。
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 380, height= 200;
04 using (Bitmap image= new Bitmap(width, height))
05 {
06 using (Graphics g=Graphics.FromImage(image))
07 {
08 using (Brush brush= new SolidBrush(Color.Black))
09 {
10 Font font= new Font("宋体 ", 12);
11 Font font1= new Font("Arial", 12);
12 g.DrawString("宋体12号 ", font,brush, 20, 20);
13 g.DrawString("Arial 12号 ", font1,brush, 20, 25+ font.Height);
14 image.Save(this.Server.MapPath("temp\\"+ "String.Png"),
15 System.Drawing.Imaging.ImageFormat.Png);
16 Image1.ImageUrl= "temp\\String.Png";
17 }
18 }//end
19 }//end
20 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
本范例中,第10~11行声明并初始化两个Font变量,指明所用字体和字体大小。12~13行在不同的位置用不同的字体分别绘制字符串“宋体12号”和“Arial 12号”。
14.2.5 Color结构
在自然界中,颜色大都由透明度(A)和三基色(R,G,B)组成。在GDI+中,通过Color结构封装对颜色的定义,Color结构中,除了提供(A,R,G,B)以外,还提供许多系统定义的颜色,如Pink(粉颜色)。另外,还提供许多静态成员,用于对颜色进行操作。
Color结构的基本属性如下表所示。
Color结构的基本(静态)方法如下表所示。
14.2.6 Point结构
用指定坐标初始化Point类的新实例,其构造函数为public Point( int x,int y ) 其中x为该点的水平位置,y为该点的垂直位置。
14.3 基本图形绘制
本节视频教学录像:15分钟
本节介绍直线、矩形、椭圆、弧线、扇形以及多边形基本图形等的绘制。
14.3.1 绘制直线和矩形
1. 绘制直线
绘制直线时,可以调用Graphics 类中的DrawLine方法。该方法为可重载方法,它主要用来绘制一条连接由坐标对指定的两个点的线条,该方法常用格式有以下两种:
⑴绘制一条连接两个Point结构的线。
Graphics g = this .CreateGraphics( );
g.DrawLine(Pen,Point pt1,Point pt2);
其中,画笔对象MyPen确定线条的颜色、宽度和样式。Pt1是Point结构,表示要连接的一个点。Pt2是Point结构,表示要连接的另一个点。
⑵绘制一条由坐标对指定的两个点的线条。
Graphics g = this .CreateGraphics( );
g. DrawLine(Pen myPen,int x1,int y1,int x2,int y2);
DrawLine 方法中各参数及说明如下表所示:
【范例14-5】创建一个ASP.NET 网站,运行之后在浏览器中显示两条平行的线。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image标签。
⑶双击页面打开Default.aspx.cs文件,引入命名空间:using System.Drawing。
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 400, hight= 150;
04 using (Bitmap image= new Bitmap(width, hight))
05 {
06 using (Graphics g=Graphics.FromImage(image))
07 {
08 Point point1= new Point(20, 20);
09 Point point2= new Point(300, 20);
10 using (Pen pen1= new Pen(Color.Blue))
11 {
12 g.Clear(Color.White);
13 g.DrawLine(pen1,point1,point2);
14 g.DrawLine(pen1, 20, 30, 300, 30);
15 image.Save(this.Server.MapPath("temp\\"+ "Lines.Png"),
16 System.Drawing.Imaging.ImageFormat.Png);
17 Image1.ImageUrl= "temp\\Lines.Png";
18 }
19 }
20 }
21 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
第8~9行声明并初始化两个Point变量分别表示坐标为(20,20)、(300,20)点。13~14行使用DrawLine方法绘制两条直线。
2. 绘制矩形
调用Grphics 类中的DrawRectangle 方法可绘制矩形。该方法为可重载方法,由坐标对、宽度和高度指定矩形,其常用格式有以下两种。
⑴绘制由Rectangle结构指定的矩形。
Graphics g = this .CreateGraphics( );
g.DrawRectangle(Pen myPen,Rectangle rect);
其中,myPen为笔Pen的对象,它确定矩形的颜色、宽度和样式。rect表示要绘制矩形的Rectangle结构。
⑵绘制由坐标对、宽度和高度指定的矩形。
Graphics g = this .CreateGraphics( );
g.DrawRectangle(Pen myPen,int x,int y,int width, int height);
DrawRectangle方法中各参数及说明如下表所示:
【范例14-6】创建一个ASP.NET 网站,在浏览器中显示两个矩形。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image标签。
⑶双击页面打开Default.aspx.cs文件,引入命名空间using System.Drawing。
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 400, hight= 250;
04 using (Bitmap image= new Bitmap(width, hight))
05 {
06 using (Graphics g=Graphics.FromImage(image))
07 {
08 Rectangle rect= new Rectangle(0, 0, 100, 100);
09 using (Pen pen1= new Pen(Color.Blue))
10 {
11 g.Clear(Color.White);
12 g.DrawRectangle(pen1, rect);
13 g.DrawRectangle(pen1, 110, 0, 100, 100);
14 image.Save(this.Server.MapPath("temp\\"+ "Rectangles.Png"),
15 System.Drawing.Imaging.ImageFormat.Png);
16 Image1.ImageUrl= "temp\\Rectangles.Png";
17 }
18 }
19 }
20 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
第8行声明并初始化了一个Rectangle类型的变量rect,第12~13行绘制两个矩形。
14.3.2 绘制椭圆、弧线和扇形
1. 绘制椭圆
调用Graphics类中的DrawEllipse方法可绘制椭圆,该方法为可重载方法。椭圆绘制边界由Rectangle结构指定,其常用格式有以下两种:
⑴绘制边界由Rectangle结构指定的椭圆。
Graphics g = this.CreateGraphics();
g.DrawEllipse(Pen myPen,Rectangle rect);
其中,myPen为笔Pen的对象,它确定曲线的颜色、宽度和样式。rect表示要绘制矩形的Rectangle结构。
⑵绘制一个由边框(该边框由一对坐标、高度和宽度指定)指定的椭圆。
Grapics g = this.CreateGraphics();
g.DrawEllipse(Pen myPen,int x,int y,int width,int height);
DrawEllipse方法中各参数及说明如下表所示。
【范例14-7】创建一个ASP.NET 网站,在浏览器中显示两个椭圆。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image标签。
⑶双击页面打开Default.aspx.cs文件,引入命名空间using System.Drawing;
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 300, hight= 250;
04 using (Bitmap image= new Bitmap(width, hight))
05 {
06 using (Graphics g=Graphics.FromImage(image))
07 {
08 Rectangle rect= new Rectangle(0, 0, 80, 50);
09 int x1= 90, y1= 0,w= 80, h= 50;
10 using (Pen pen1= new Pen(Color.Blue))
11 {
12 g.Clear(Color.White);
13 g.DrawEllipse(pen1, rect);
14 g.DrawEllipse(pen1, x1, y1,w, h);
15 image.Save(this.Server.MapPath("temp\\"+ "Ellipses.Png"),
16 System.Drawing.Imaging.ImageFormat.Png);
17 Image1.ImageUrl= "temp\\Ellipses.Png";
18 }
19 }
20 }
21 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
第8行声明并初始化了一个Rectangle类型的变量rect,13~14行使用DrawEllipse方法绘制两个椭圆。
2. 绘制弧线
调用Graphics类中的DrawArc方法可绘制圆弧,该方法为可重载方法。绘制一段弧线,其常用格式有以下两种:
⑴由Rectangle结构指定的椭圆的一部分绘制一段弧线。
Graphics g = this.CreateGraphics();
g.DrawArc(Pen myPen,Rectangle rect,int startAngle,int sweeoAngle);
其中,myPen为笔Pen的对象,它确定矩形的颜色、宽度和样式。rect表示要绘制矩形的Rectangle结构。
⑵由一对坐标、宽度和高度指定的椭圆部分绘制一段弧线。
Graphics g = this.CreateGraphics();
g.DrawArc(Pen myPen,int x,int y,int width,int height,int startAngle,int sweepAngle);
DrawArc方法中各参数及说明如下表所示。
【范例14-8】创建一个ASP.NET 网站,在浏览器中显示两条弧线。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image标签。
⑶双击页面打开Default.aspx.cs文件,引入命名空间using System.Drawing。
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 300, height= 250;
04 int x= 0, y= 10;
05 int R_width= 150,R_height= 100;
06 int startAngle= 30, sweepAngle= 120;
07
08 Rectangle rect= new Rectangle(0, 0,R_width,R_height);
09 using (Bitmap bmp= new Bitmap(width, height))
10 {
11 using (Graphics g=Graphics.FromImage(bmp))
12 {
13 g.Clear(Color.White);
14 using (Pen pen= new Pen(Color.Blue, 5))
15 {
16 g.DrawArc(pen, rect, startAngle, sweepAngle);
17 g.DrawArc(pen, x, y,R_width,R_height, startAngle, sweepAngle);
18 bmp.Save(this.Server.MapPath("temp\\"+ "Arcs.Png"),
19 System.Drawing.Imaging.ImageFormat.Png);
20 Image1.ImageUrl= "temp\\Arcs.Png";
21 }
22 }
23 }
24 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
第8行声明并初始化了一个Rectangle类型的变量rect,16~17行使用DrawArc方法绘制两个弧线。
3. 绘制扇形
调用Graphics类中的DrawPie方法可绘制扇形,该方法为可重载方法。绘制扇形,其常用格式有以下两种:
⑴由一个Rectangle结构和两条射线所指定的椭圆指定的扇形
G7raphics g = new this.CreateGraphics();
DrawPie(Pen pen, Rectangle rect, float startAngle, float sweepAngle);
⑵由一个坐标对、宽度和高度以及两条射线所指定的椭圆指定的扇形
Graphics g = this.CreateGraphics();
DrawPie(Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle);
DrawPie方法中各参数及说明如下表所示。
【范例14-9】创建一个ASP.NET网站,在浏览器中显示两个扇形。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image标签。
⑶双击页面打开Default.aspx.cs文件,引入命名空间using System.Drawing;
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 300, height= 250;
04 int x= 0, y= 10;
05 int R_width= 150,R_height= 100;
06 int startAngle= 30, sweepAngle= 120;
07
08 Rectangle rect= new Rectangle(0, 0,R_width,R_height);
09 using (Bitmap bmp= new Bitmap(width, height))
10 {
11 using (Graphics g=Graphics.FromImage(bmp))
12 {
13 g.Clear(Color.White);
14 using (Pen pen= new Pen(Color.Blue, 5))
15 {
16 g.DrawPie(pen, rect, startAngle, sweepAngle);
17 g.DrawPie(pen, x, y,R_width,R_height, startAngle, sweepAngle);
18 bmp.Save(this.Server.MapPath("temp\\"+ "Pies.Png"),
19 System.Drawing.Imaging.ImageFormat.Png);
20 Image1.ImageUrl="temp\\Pies.png";
21 }
22 }//end
23 }//end
24 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
第8行声明并初始化了一个Rectangle类型的变量rect,16~17行使用DrawPie方法绘制两个扇形。
14.3.3 绘制多边形
绘制多边形需要Graphics对象、Pen对象和Point或PointF(对象数组)。Graphics对象提供DrawPolygon方法绘制多边形;Pen对象存储用于呈现多边形的线条属性,如宽度和颜色等;Point存储多边形的各个顶点。Pen对象和Point或PointF作为参数传递给DrawPolygon方法。其中,数组中每对相邻的两个点指定多边形的一条边。另外,如果数组的最后一个点和第一个点不重合,则这两个指定多边形的最后一条边,其常用格式有以下两种。
⑴绘制由一组Point结构定义的多边形。
Graphics g = this.CreateGraphics();
g.DrawPolygon(Pen myPen,Point[] points);
⑵绘制由一组PointF结构定义的多边形。
Graphics g = this.CreateGraphics();
g.DrawPolygon(Pen mypen, PointF[] points);
【范例14-10】创建一个ASP.NET网站,在浏览器中显示两个多边形。
⑴打开Visual Studio 2010,新建一个ASP.NET空网站,添加一个Deafault.aspx窗体和temp文件夹。
⑵切换到设计视图并添加一个Image标签。
⑶双击页面打开Default.aspx.cs文件,引入命名空间using System.Drawing;
⑷在Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 int width= 300, height= 250;
04 Point p1= new Point(30, 30);PointF pf1= new PointF(130.0f, 30.0f);
05 Point p2= new Point(60, 10);PointF pf2= new PointF(160.0f, 10.0f);
06 Point p3= new Point(100, 60);PointF pf3= new PointF(200.0f,60.0f);
07 Point p4= new Point(60, 120);PointF pf4= new PointF(160.0f, 120.0f);
08
09 Point[] points= {p1,p2,p3,p4};
10 PointF[] pointFs= {pf1,pf2,pf3,pf4};
11
12 using (Bitmap bmp= new Bitmap(width, height))
13 {
14 using (Graphics g=Graphics.FromImage(bmp))
15 {
16 g.Clear(Color.White);
17 using (Pen pen= new Pen(Color.Blue, 5))
18 {
19 g.DrawPolygon(pen,points);
20 g.DrawPolygon(pen,pointFs);
21 bmp.Save(this.Server.MapPath("temp\\"+ "Polygons.Png"),
22 System.Drawing.Imaging.ImageFormat.Png);
23 Image1.ImageUrl= "temp\\Polygons.png";
24 }
25 }//end
26 }//end
27 }//end
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
【范例分析】
本范例中,第4~7行声明并初始化了Point类型和PointF类型的变量各4个。第9~10行声明并初始化了Point和PointF类型的数组。第16行创建了一个蓝色、宽度为5的Pen对象。第19~20行使用Graphics对象g的DrawPolygon方法绘制多边形。
14.4 综合应用
本节视频教学录像:6分钟
本节通过一个实例介绍GDI+的应用。
【范例14-11】建立创建一个ASP.NET网站,在浏览器中显示验证码。
⑴打开 Visual Studio 2010,新建一个 ASP.NET 空网站,添加一个 Deafault.aspx 窗体、一个Success.aspx窗体和Handler.ashx 一般处理程序。
⑵在资源浏览器中双击Handler.ashx打开Handler.ashx,在该文件中引入以下命名空间。
01 using System.Drawing;
02 using System.Text;
03 using System.Web.SessionState;
04 using System.Drawing.Imaging;
⑶编辑类Handler,具体代码如下所示。
01 public class Handler : IHttpHandler,IRequiresSessionState {
02
03 public void ProcessRequest (HttpContext context) {
04 context.Response.ContentType= "image/gif";
05 //建立对象,绘图
06 Bitmap basemap= new Bitmap(200, 60);
07 Graphics graph=Graphics.FromImage(basemap);
08 graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);
09 Font font= new Font(Font Family.GenericSerif, 48, FontStyle.Bold,GraphicsUnit.Pixel);
10 Random r= new Random();
11 string letters= "ABCDEFGHIJKLMNPQRSTUVWXYZ1234567890";
12 string letter;
13 StringBuilder s= new StringBuilder();
14
15 //添加随机的五个字母
16 for (int x= 0; x< 5; x++)
17 {
18 letter= letters.Substring(r.Next(0, letters.Length - 1), 1);
19 s.Append(letter);
20 graph.DrawString(letter, font, newSolidBrush(Color.Black), x * 38, r.Next(0, 15));
21 }
22 //混淆背景
23 Pen linePen= new Pen(newSolidBrush(Color.Black), 2);
24 for (int x= 0; x< 6; x++)
25 graph.DrawLine(linePen, new Point(r.Next(0, 199), r.Next(0, 59)), new Point(r.Next(0, 199),r.Next(0, 59))) ;
26 //将图片保存到输出流中
27 basemap.Save(context.Response.OutputStream, ImageFormat.Gif);
28 context.Session["CheckCode"]= s.ToString();
29 //如果没有 IRequiresSessionState,则这里会出错,也无法生成图片
30 context.Response.End();
31 }
32 public bool IsReusable {
33 get {
34 return true;
35 }
36 }
37 }
⑷在解决方案资源管理器中双击“Default.aspx”并切换到设计视图,向页面添加一个HTML类型的Table控件,三个标准类型的TextBox控件,一个Image控件和一个标准类型的Button控件,最终页面布局以及属性设置如下图所示。Image控件的ImageUrl属性设置为“~/Handler.ashx”。
⑸双击“确认”按钮打开Default.aspx.cs文件,在Button1_Click()事件中添加以下代码。
01 protected void Button1_Click(object sender,EventArgs e)
02 {
03 String str= (String) this.Session["CheckCode"];
04 if (!str.Equals(TextBox3.Text))
05 {
06 this.Response.Redirect("Default.aspx");
07 }
08 else
09 {
10 this.Session["YanZhengMa"]= "输的验证码正确! ";
11 this.Response.Redirect("Success.aspx");
12 }
13 }
⑹在解决方案资源管理器中双击“Success.aspx.cs”打开 Success.aspx.cs 文件,在 Page_Load()事件中添加以下代码。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 if (this.Session["YanZhengMa"] != null)
04 {
05 this.Response.Write(String.Format(this.Session["YanZhengMa"].ToString()));
06 }
07 }
【运行结果】
按【F5】键调试并运行,浏览器中的运行结果如图所示。
在对应的文本框中输入验证码。
单击“确定”按钮。
如果输入的验证码不正确,则跳转到原页面(不过生成的验证码发生了变化)。
【范例分析】
步骤⑶中第6~7行创建Graphics对象,声明并初始化了一个Rectangle类型的变量rect,第8行绘制一个内部由白色画刷填充的矩形,第9行声明并初始化了一个字体变量font,第10、18两行代码的作用是从字符串letters中随机得到一个长度为1的子串,第20行绘制指定样式的字符串,第24~26行在指定在一定平面内随机绘制六条线段。
步骤⑷中的Image控件用来显示Handler.ashx生成的验证码图片,因此其ImageUrl的写法为ImageUrl="~/Handler.ashx"。
步骤⑸中的第3行通过强制类型转换从Session中得到下标为“CheckCode”的元素即生成的验证码字符串;第4~12行指定如果输入的验证码不正确则跳转到页面Default.aspx即原页面,如果正确则将一个字符串存入Session中,并跳转到Success.aspx页面。
步骤⑹中第3~6行输出步骤⑸中第10行中存入Session的字符串。
14.5 高手点拨
本节视频教学录像:2分钟
绘制的图片失真的原因
当图片显示在页面中时,若出现失真现象,不是因为绘图时出现了问题,而是保存图片格式时出现了问题,例如:
Bit.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
Response.ContentType=”image/Gif”;
这时显示的图片就有可能失真,将Gif格式改为Jpeg格式即可。
14.6 实战练习
设计一个网站,实现在浏览器中绘制各种图形。