46
1 第8第 第第 GDI+ 第 .NET 第第

第 8 讲 使用 GDI+ 的 .NET 图形

Embed Size (px)

DESCRIPTION

第 8 讲 使用 GDI+ 的 .NET 图形. 主要内容. 8.1 GDI+ 概述 8.2 使用 Graphics 对象 8.3 字体和文本绘制 8.4 图像处理. 8.1 GDI+ 概述. 8.1.1 GDI+ 的基本概念 GDI : 即 Graphics Device Interface ,图形设备接口 初级的 GDI 绘图机制很复杂,首先获得一个显示设备环境( DC )、通过 DC 才能绘图、还要考虑显示模式、重绘等等。 GDI+ 以图形图像作为对象,可在 Windows 窗体应用程序中以编程方式绘制或操作图形图像。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第 8 讲 使用 GDI+ 的 .NET 图形

1

第 8 讲使用 GDI+的 .NET 图

Page 2: 第 8 讲 使用 GDI+ 的 .NET 图形

2/47

主要内容 8.1 GDI+ 概述 8.2 使用 Graphics 对象 8.3 字体和文本绘制 8.4 图像处理

Page 3: 第 8 讲 使用 GDI+ 的 .NET 图形

3/47

8.1 GDI+ 概述 8.1.1 GDI+ 的基本概念

GDI :即 Graphics Device Interface ,图形设备接口

初级的 GDI 绘图机制很复杂,首先获得一个显示设备环境( DC )、通过 DC 才能绘图、还要考虑显示模式、重绘等等。

GDI+ 以图形图像作为对象,可在 Windows 窗体应用程序中以编程方式绘制或操作图形图像。

总而言之, GDI+ 解决了 GDI 中的许多问题,可使用户更容易使用这些接口来绘制图形。

Page 4: 第 8 讲 使用 GDI+ 的 .NET 图形

4/47

8.1.2 GDI+ 的绘图命名空间所有的 GDI+ 函数都保存在 System.Drawing.dll程序集中 , 使用之前 , 必须添加相应的引用

Page 5: 第 8 讲 使用 GDI+ 的 .NET 图形

5/47

8.1.2 GDI+ 的绘图命名空间( 2 )主要的绘图命名空间 System.Drawing 、 System.Drawing.Text 、 System.Drawing.Printing 、

System.Drawing.Imaging 、 System.Drawing.Drawing2D 、

System.Drawing.Design

Page 6: 第 8 讲 使用 GDI+ 的 .NET 图形

6/47

主要内容 8.1 GDI+ 概述 8.2 使用 Graphics 对象 8.3 图像处理 8.4 字体和文本绘制

Page 7: 第 8 讲 使用 GDI+ 的 .NET 图形

7/47

8.2 使用 Graphics 对象

8.2.1 创建 Graphics对象8.2.2 Pen对象8.2.3 Brush对象8.2.4 常用图形的绘制方法 8.2.5 典型实例

Page 8: 第 8 讲 使用 GDI+ 的 .NET 图形

8/47

8.2.1 创建 Graphics对象1 、在 GDI+ 的所有类中, Graphics 类是核心,创建的

Graphics 对象相当于一张画布。可以调用绘图方法在其上画图。

一般,图形设计过程分为两步:创建 Graphics 对象、使用 Graphics 对象的方法进行绘图。

2 、创建 Graphics 对象的方法一般有三种:A 、利用窗体或控件的 Paint 事件的参数

PaintEventArgsprivate void Form1_Paint(object sender,

System.Windows.Forms.PaintEventArgs e){

Graphics g=e.Graphics;}

Page 9: 第 8 讲 使用 GDI+ 的 .NET 图形

9/47

B 、(一般使用)使用窗体或控件的 CreateGraphics 方法,用于对象已经存在的情况下:

Graphics g;

g=this.CreateGraphics();

C 、使用 Image 类的派生类创建 Graphics 对象,用于在C# 中对图像进行处理的场合:

Bitmap b=new Bitmap("ddd.bmp");

Graphics g=Graphics.FromImage(b);

Page 10: 第 8 讲 使用 GDI+ 的 .NET 图形

10/47

8.2.2 Pen对象

Pen 对象又称为画笔对象。用途:绘制线条、多边形、曲线等几何图形。Pen 对象的主要属性:宽度、样式、颜色。1 、 Pen 对象的创建( 4 种形式)Pen p1=new Pen(Color);// 创建某一颜色的 Pen 对象Pen p2=new Pen(Brush);// 创建某一刷子样式的 Pen 对象Pen p3=new Pen(Brush,float);// 创建某一刷子样式并具有

相应宽度的的 Pen 对象Pen p4=new Pen(Color,float);// 创建某一颜色和相应宽度的 Pen 对象

Page 11: 第 8 讲 使用 GDI+ 的 .NET 图形

11/47

例 1 在窗体上画椭圆和直线:private void button1_Click(object sender,

System.EventArgs e){

Graphics g=this.CreateGraphics();Pen p1=new Pen(Color.Red);g.DrawEllipse(p1,20,30,10,50);// 画椭圆g.DrawLine(p1,1,1,400,6000);// 画直线

}

Page 12: 第 8 讲 使用 GDI+ 的 .NET 图形

12/47

2、 Pen 对象的常用属性Alignment :设置 Pen 对象的对齐方式;Color :设置 Pen 对象的颜色Width :设置 Pen 对象的宽度DashStyle :设置 Pen 对象绘制的虚线样式,只能取 6

个值: Custom、 Dash、 DashDot、 DashDotDot、Dot、 Solid

DashCap :指定虚线的两端风格, Flat、 Round、 Triagle

StartCap :设置 Pen 对象绘制直线起点的帽样式EndCap :设置 Pen 对象的对象绘制直线终点的帽样式PenType :设置 Pen 对象对象绘制直线的样式使用举例: p1.Color=Color.Blue;

p1.DashStyle=DashStyle.Solid;p1.DashCap=DashCap.Flat;

Page 13: 第 8 讲 使用 GDI+ 的 .NET 图形

13/47

8.2.3 Brush对象(画刷)

作用:一般用来填充图形。Brush 类是一个抽象类,不能实例化,只能使用它的派生类:SolidBrush (单色画刷)(包含在命名空间 System.Drawing 中)、HatchBrush (阴影画刷)、LinearGradientBrush (颜色渐变画刷)、PathGradientBrush (使用路径及复杂的混色渐变画刷)、TextureBrush (纹理画刷)(后三个包含在命名空间 System.Drawing. Drawing2D 中)

Page 14: 第 8 讲 使用 GDI+ 的 .NET 图形

14/47

1、 SolidBrush (单色画刷)使用格式: SolidBrush ff=new SolidBrush(Color.Red);

例 2 在窗体上绘制红色的椭圆Graphics g=this.CreateGraphics();

SolidBrush ff=new SolidBrush(Color.Red);

g.FillEllipse(ff,ClientRectangle);

Page 15: 第 8 讲 使用 GDI+ 的 .NET 图形

15/47

2、 HatchBrush (阴影画刷)使用格式:A、 HatchBrush ff=new

HatchBrush(HatchStyle,Color);//Color 为前景颜色B、 HatchBrush ff=new

HatchBrush(HatchStyle,Color , Color);// 第一个Color 为前景颜色,第二个为背景色

其中 HatchStyle 取值固定,为阴影方式,如下图:注意:使用 HatchBrush (阴影画刷)一定要添加相应的

引用,并使用命名空间 using System.Drawing.Drawing2D;

Page 16: 第 8 讲 使用 GDI+ 的 .NET 图形

16/47

例 3 在窗体上绘制阴影的椭圆Graphics g=this.CreateGraphics();

HatchBrush ff=new HatchBrush(HatchStyle.Cross,Color.Blue,Color.Red);

g.FillEllipse(ff,ClientRectangle);

Page 17: 第 8 讲 使用 GDI+ 的 .NET 图形

17/47

3、 LinearGradientBrush (颜色渐变画刷)常用的渐变效果由两个颜色逐渐变化而来。常用的使用格式:LinearGradientBrush ff=new

LinearGradientBrush(Point1, Point2,Color1,Color2);其中, Point1 为渐变的起点, Point2 为渐变的终

点, Color1 为渐变的起点颜色, Color2 为渐变的终点颜色

例 4 在窗体上绘制渐变颜色的椭圆 Graphics g=this.CreateGraphics();

LinearGradientBrush ff=new LinearGradientBrush(new Point(0,20),new Point(20,0),Color.Yellow,Color.Blue);

g.FillEllipse(ff,ClientRectangle);

Page 18: 第 8 讲 使用 GDI+ 的 .NET 图形

18/47

8.2.4 常用图形的绘制方法1 、画直线使用 Graphics 类的 DrawLine 方法,格式为:DrawLine( 画笔 ,x1,y1,x2,y2)功能:在点( x1,y1) ,( x2,y2 )之间画一条直线。

例如画两条直线Graphics g=this.CreateGraphics();// 生成图形对象Pen Mypen=new Pen(Color.Blue ,5);// 生成画笔 , 蓝

色, 5 个像素g.DrawLine(Mypen,1,1,30,30);// 画线Point pt1=new Point(1,30);// 生成起点Point pt2=new Point(30,1);// 生成终点g.DrawLine(Mypen,pt1,pt2);// 画线

Page 19: 第 8 讲 使用 GDI+ 的 .NET 图形

19/47

2 、画椭圆使用 Graphics 类的 DrawEllipse 方法,格式为:A、 DrawEllipse ( 画笔 , 矩形结构数据 )功能:绘制一个边界由矩形结构数据定义的椭圆。B、 DrawEllipse ( 画笔 ,x, y, width, height)功能:绘制一个由边框定义的椭圆。

例如画一个椭圆Graphics g=this.CreateGraphics();// 生成图形对象Pen Mypen=new Pen(Color.Blue ,5);// 生成画笔 , 蓝色,

5 个像素g.DrawEllipse(Mypen,1,1,80,40);// 画椭圆Rectangle rect=new Rectangle(85,1,165,40);// 生成矩

形g.DrawEllipse (Mypen,rect);// 画椭圆

Page 20: 第 8 讲 使用 GDI+ 的 .NET 图形

20/47

3 、画圆弧使用 Graphics 类的 DrawArc 方法,格式为:A、 DrawArc ( 画笔 , 矩形结构数据,实数,实数 )

功能:绘制由指定矩形的内接椭圆的一段圆弧。B、 DrawArc ( 画笔 ,x, y, width, height ,整数,整数 )

功能:绘制一段弧线,该弧线由一对坐标、宽度、高度指定椭圆的一段圆弧。例 5 画一段圆弧Graphics g=this.CreateGraphics();//生成图形对象Pen Mypen=new Pen(Color.Blue ,5);//生成画笔 ,蓝色, 5个像素

g.DrawArc(Mypen,1,1,80,40,90,270);//画弧线Rectangle rect=new Rectangle(85,1,165,40);// 生成起点 生成矩形结构

g.DrawArc (Mypen,rect,0,90);//画弧线

Page 21: 第 8 讲 使用 GDI+ 的 .NET 图形

21/47

4 、画扇形图使用 Graphics 类的 DrawPie 方法,格式与 DrawArc 基本

相同

例 6 画两个扇形Graphics g=this.CreateGraphics();// 生成图形对象Pen Mypen=new Pen(Color.Blue ,5);// 生成画笔 , 蓝色, 5

个像素g.DrawPie(Mypen,1,1,80,40,90,270);// 画扇形Rectangle rect=new Rectangle(85,1,165,40);// 生成矩形g.DrawPie (Mypen,rect,0,90);// 画扇形

Page 22: 第 8 讲 使用 GDI+ 的 .NET 图形

22/47

5 、画矩形使用 Graphics 类的 DrawRectangle 方法,格式为:A、 DrawRectangle ( 画笔 , 矩形结构数据 )

功能:绘制一个边界由矩形结构数据定义的矩形。B、 DrawRectangle ( 画笔 ,x, y, width, height)

功能:绘制一个由左上角坐标、宽度、高度定义的矩形。例 7 画一个矩形Graphics g=this.CreateGraphics();//生成图形对象Pen Mypen=new Pen(Color.Blue ,2);//生成画笔 ,蓝色, 2个像素

g.DrawRectangle (Mypen,5,5,80,40);//画矩形Rectangle rect=new Rectangle(85,15,140,50);//生成矩形g.DrawRectangle (Mypen,rect);//画矩形

Page 23: 第 8 讲 使用 GDI+ 的 .NET 图形

23/47

6 、画多边形使用 Graphics 类的 DrawPolygon 方法,格式为:A、 DrawPolygon ( 画笔 ,Point[] points)

功能:绘制由一组 Point 结构定义的多边形。B、 DrawPolygon ( 画笔 ,PointF[] points)

功能:绘制由一组 PointF 结构定义的多边形Point 结构只能取整数, PointF 可以取实数

Page 24: 第 8 讲 使用 GDI+ 的 .NET 图形

24/47

例 8 画一个多边形Pen blackPen = new Pen(Color.Black, 3);//生成画笔 ;Graphics g=this.CreateGraphics();//生成图形对象Point point1 = new Point( 50, 50);//生成 5个点Point point2 = new Point(70, 25);Point point3 = new

Point(100, 30);Point point4 = new Point(120, 85);Point point5 = new

Point(80, 100);Point[] curvePoints

={point1,point2,point3,point4,point5};//定义 Point结构的数组g.DrawPolygon(blackPen, curvePoints);//绘制多边形

Page 25: 第 8 讲 使用 GDI+ 的 .NET 图形

25/47

7 、填充椭圆使用 Graphics 类的 FillEllipse 方法,格式为:A 、 FillEllipse(Brush F, 矩形结构数据 )

功能:填充边界由矩形结构数据定义的椭圆。B 、 FillEllipse(Brush F,x, y, width, height)

功能:填充一个由边框(坐标、宽度、高度)定义的椭圆。

Page 26: 第 8 讲 使用 GDI+ 的 .NET 图形

26/47

8 、填充矩形使用 Graphics 类的 FillRectangle 方法,格式为:A 、 FillRectangle(Brush F, 矩形结构数据 )

功能:用指定的画刷填充一个矩形。B 、 FillRectangle (Brush F,x, y, width, height)

功能:填充一个由边框(坐标、宽度、高度)定义的矩形。

Page 27: 第 8 讲 使用 GDI+ 的 .NET 图形

27/47

例 9 填充一个矩形Graphics g=this.CreateGraphics();// 生成图形对象SolidBrush BlueBrush = new SolidBrush(Color.Blue);// 生成

填充用的画刷int x = 15;// 定义外接矩形的左上角坐标和高度及宽度int y = 15;int width = 200;int height = 100;Rectangle rect = new Rectangle( x, y, width, height);// 定义

矩形g.FillRectangle(BlueBrush,rect);// 填充矩形

Page 28: 第 8 讲 使用 GDI+ 的 .NET 图形

28/47

8.2.5 典型实例一

利用鼠标画图编写一个利用鼠标在窗体上画图的程序,无论何时用户按下

并拖动鼠标均会画出一条线。实现方法;使用 MouseDown (开始画图)、 MouseUp

(结束画图)、 MouseMove (执行画图)

Page 29: 第 8 讲 使用 GDI+ 的 .NET 图形

29/47

8.2.5 典型实例二

模拟石英钟在窗口中模拟一个石英钟实现方法:

Timer, PaintEventHandler, CreateGraphics

Page 30: 第 8 讲 使用 GDI+ 的 .NET 图形

30/47

主要内容 8.1 GDI+ 概述 8.2 使用 Graphics 对象 8.3 字体和文本绘制 8.4 图像处理

Page 31: 第 8 讲 使用 GDI+ 的 .NET 图形

31/47

GDI+ 的字体支持 TrueType和 OpenType 字体

Page 32: 第 8 讲 使用 GDI+ 的 .NET 图形

32/47

Font Families

创建 FontFamily 对象

FontFamily ff = new FontFamily("Arial");

FontFamily ff = new FontFamily(GenericFontFamilies.Monospace);

Page 33: 第 8 讲 使用 GDI+ 的 .NET 图形

33/47

创建 Font 对象

FontFamily ff = new FontFamily("Arial"); Font normFont = new Font(ff,10); // Arial Regular 10 pt.

Font normFont = new Font("Arial",10) // Arial Regular 10 point

Font boldFont = new Font("Arial",10,FontStyle.Bold); Font bldItFont = new Font("Arial",10, FontStyle.Bold | FontStyle.Italic); // Arial bold italic 10

提供多个构造函数

Page 34: 第 8 讲 使用 GDI+ 的 .NET 图形

34/47

绘制文本串 DrawString 方法

Font regFont = new Font("Tahoma",12); String s = "ice mast high came floating by as

green as emerald."; // Draw text beginning at coordinates (20,5) g.DrawString(s, regFont, Brushes.Black, 20,5); regFont.Dispose();

Page 35: 第 8 讲 使用 GDI+ 的 .NET 图形

35/47

绘制多行文本Font regFont = new Font("Tahoma",12); String s = “ice mast high came floating by as green as emerald.” ;int lineWidth = 200; SizeF sf = g.MeasureString(s, regFont, lineWidth); // Create rectangular drawing area based on return // height and width RectangleF rf = new RectangleF(20,5,sf.Width, sf.Height); // Draw text in rectangle g.Drawstring(s,regFont,Brushes.Black, rf); // Draw rectangle around text g.DrawRectangle(Pens.Red,20F,5F,rf.Width, rf.Height);

Page 36: 第 8 讲 使用 GDI+ 的 .NET 图形

36/47

截断、对齐和自动换行 StringFormat的 Trimming和 Alignment 属

性控制如何将文本放置在矩形框里面Font fnt = new Font("Tahoma",10,FontStyle.Bold); RectangleF r = new RectangleF(5,5,220,60); string txt = "dew drops are the gems of morning"; g.DrawString(txt,fnt,Brushes.Black,r); g.DrawRectangle(Pens.Red,r.X,r.Y,r.Width,r.Height);

Page 37: 第 8 讲 使用 GDI+ 的 .NET 图形

37/47

禁止换行StringFormat strFmt = new StringFormat(); strFmt.FormatFlags = StringFormatFlags.NoWrap; g.DrawString(txt,fnt,Brushes.Black,r,strFmt);

截断到单词、靠右StringFormat strFmt = new StringFormat(); strFmt.Trimming = StringTrimming.Word; strFmt.Alignment = StringAlignment.Far; g.DrawString(txt,fnt,Brushes.Black,r,strFmt);

Page 38: 第 8 讲 使用 GDI+ 的 .NET 图形

38/47

主要内容 8.1 GDI+ 概述 8.2 使用 Graphics 对象 8.3 字体和文本绘制 8.4 图像处理

Page 39: 第 8 讲 使用 GDI+ 的 .NET 图形

39/47

8.4 图像处理

Image和 Bitmap 类主要功能: 图像的加载和存储 图像的显示 图像处理

Page 40: 第 8 讲 使用 GDI+ 的 .NET 图形

40/47

图像的加载和存储

创建 Bitmap 类

string fname = "c:\\globe.gif"; Bitmap bmp = new Bitmap(fname);

bmp = (Bitmap)Bitmap.FromFile(fname);

Page 41: 第 8 讲 使用 GDI+ 的 .NET 图形

41/47

多种格式支持支持大部分图像格式

JPEGGIFPNGTIFF…

可以方便地在不同格式间转换

Page 42: 第 8 讲 使用 GDI+ 的 .NET 图形

42/47

格式转换例 12 GIF转换成 JPEG

string fname = "c:\\globe.gif"; bmp = new Bitmap(Image.FromFile(fname)); bmp.Save("c:\\globe.jpg", ImageFormat.Jpeg);

Page 43: 第 8 讲 使用 GDI+ 的 .NET 图形

43/47

图像的显示

使用 Graphics 对象的 DrawImage 方法 该方法有多个重载版本,用于对图像的大小、位置等进行控制

按实际大小绘制Graphics g = panel1.CreateGraphics(); g.DrawImage(bmp,0,0);

Page 44: 第 8 讲 使用 GDI+ 的 .NET 图形

44/47

指定绘制区域Rectangle dRect = new Rectangle(new Point(0,0),

new Size(panel1.Width,panel1.Height)); g.DrawImage(bmp, dRect); //Or panel1.ClientRectangle

指定图像区域Rectangle sRect = new Rectangle(

new Point(100,0), new Size(192,160)); g.DrawImage(bmp,0,0,sRect,GraphicsUnit.Pixel);

指定图像显示的定点Point[]dp = {new Point(10,0),new Point(80,10),

new Point(0,70)}; // ul, ur, ll g.DrawImage(bmp,dp);

Page 45: 第 8 讲 使用 GDI+ 的 .NET 图形

45/47

图像镜像指定定点法Bitmap bmp = new Bitmap(fname); // Get image

// Mirror Image Point ptA = new Point(bmp.Width,0); // Upper left Point ptB = new Point(0,0); // Upper right Point ptC = new Point(bmp.Width, bmp.Height); // Lower left Point[]dp = {ptA,ptB,ptC}; g.DrawImage(bmp,dp);

RotateFlip 法// Flip horizontally (mirror)

bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);

Page 46: 第 8 讲 使用 GDI+ 的 .NET 图形

46/47

改变图像的像素值Bitmap bmpMem = …

for (int y=0; y<bmpMem.Height; y++) { for (int x=0; x<bmpMem.Width; x++) { Color px = bmpMem.GetPixel(x,y);

if(px.G > 240) bmpMem.SetPixel(x,y, cnRed); // Set white to red else bmpMem.SetPixel(x,y,Color.White); // Set red to white }

}