460 likes | 700 Views
第 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 窗体应用程序中以编程方式绘制或操作图形图像。
E N D
主要内容 • 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窗体应用程序中以编程方式绘制或操作图形图像。 • 总而言之, GDI+ 解决了GDI中的许多问题,可使用户更容易使用这些接口来绘制图形。
8.1.2 GDI+的绘图命名空间 所有的GDI+ 函数都保存在System.Drawing.dll程序集中, 使用之前,必须添加相应的引用
8.1.2 GDI+的绘图命名空间(2) 主要的绘图命名空间 System.Drawing、 System.Drawing.Text、 System.Drawing.Printing、 System.Drawing.Imaging、 System.Drawing.Drawing2D、 System.Drawing.Design
主要内容 • 8.1 GDI+概述 • 8.2 使用Graphics对象 • 8.3 图像处理 • 8.4 字体和文本绘制
8.2 使用Graphics对象 8.2.1 创建Graphics对象 8.2.2 Pen对象 8.2.3 Brush对象 8.2.4 常用图形的绘制方法 8.2.5 典型实例
8.2.1 创建Graphics对象 1、在GDI+的所有类中,Graphics类是核心,创建的Graphics对象相当于一张画布。可以调用绘图方法在其上画图。 一般,图形设计过程分为两步:创建Graphics对象、使用Graphics对象的方法进行绘图。 2、创建Graphics对象的方法一般有三种: A、利用窗体或控件的Paint事件的参数PaintEventArgs private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { Graphics g=e.Graphics; }
B、(一般使用)使用窗体或控件的CreateGraphics方法,用于对象已经存在的情况下:B、(一般使用)使用窗体或控件的CreateGraphics方法,用于对象已经存在的情况下: Graphics g; g=this.CreateGraphics(); C、使用Image类的派生类创建Graphics对象,用于在C#中对图像进行处理的场合: Bitmap b=new Bitmap("ddd.bmp"); Graphics g=Graphics.FromImage(b);
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 对象
例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);//画直线 }
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;
8.2.3 Brush对象(画刷) 作用:一般用来填充图形。 Brush类是一个抽象类,不能实例化,只能使用它的派生类: SolidBrush(单色画刷) (包含在命名空间System.Drawing中)、 HatchBrush(阴影画刷)、 LinearGradientBrush(颜色渐变画刷)、 PathGradientBrush(使用路径及复杂的混色渐变画刷)、 TextureBrush(纹理画刷) (后三个包含在命名空间System.Drawing. Drawing2D中)
1、SolidBrush(单色画刷) 使用格式:SolidBrush ff=new SolidBrush(Color.Red); 例2 在窗体上绘制红色的椭圆 Graphics g=this.CreateGraphics(); SolidBrush ff=new SolidBrush(Color.Red); g.FillEllipse(ff,ClientRectangle);
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;
例3 在窗体上绘制阴影的椭圆 Graphics g=this.CreateGraphics(); HatchBrush ff=new HatchBrush(HatchStyle.Cross,Color.Blue,Color.Red); g.FillEllipse(ff,ClientRectangle);
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);
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);//画线
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);//画椭圆
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);//画弧线
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);//画扇形
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);//画矩形
6、画多边形 使用Graphics类的DrawPolygon方法,格式为: A、DrawPolygon (画笔,Point[] points) 功能:绘制由一组Point结构定义的多边形。 B、DrawPolygon (画笔,PointF[] points) 功能:绘制由一组PointF结构定义的多边形 Point 结构只能取整数,PointF可以取实数
例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);//绘制多边形
7、填充椭圆 使用Graphics类的FillEllipse方法,格式为: A、 FillEllipse(Brush F,矩形结构数据) 功能:填充边界由矩形结构数据定义的椭圆。 B、 FillEllipse(Brush F,x,y,width,height) 功能:填充一个由边框(坐标、宽度、高度)定义的椭圆。
8、填充矩形 使用Graphics类的FillRectangle方法,格式为: A、 FillRectangle(Brush F,矩形结构数据) 功能:用指定的画刷填充一个矩形。 B、 FillRectangle (Brush F,x,y,width,height) 功能:填充一个由边框(坐标、宽度、高度)定义的矩形。
例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);//填充矩形
8.2.5 典型实例一 利用鼠标画图 编写一个利用鼠标在窗体上画图的程序,无论何时用户按下并拖动鼠标均会画出一条线。 实现方法;使用MouseDown(开始画图)、MouseUp(结束画图)、MouseMove(执行画图)
8.2.5 典型实例二 模拟石英钟 在窗口中模拟一个石英钟 实现方法:Timer,PaintEventHandler,CreateGraphics
主要内容 • 8.1 GDI+概述 • 8.2 使用Graphics对象 • 8.3 字体和文本绘制 • 8.4 图像处理
GDI+的字体支持 • TrueType和OpenType字体
Font Families • 创建FontFamily对象 FontFamily ff = new FontFamily("Arial"); FontFamily ff = new FontFamily( GenericFontFamilies.Monospace);
创建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
绘制文本串 • 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();
绘制多行文本 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);
截断、对齐和自动换行 • 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);
禁止换行 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);
主要内容 • 8.1 GDI+概述 • 8.2 使用Graphics对象 • 8.3 字体和文本绘制 • 8.4 图像处理
8.4 图像处理 Image和Bitmap类 主要功能: • 图像的加载和存储 • 图像的显示 • 图像处理
图像的加载和存储 • 创建Bitmap类 string fname = "c:\\globe.gif"; Bitmap bmp = new Bitmap(fname); bmp = (Bitmap)Bitmap.FromFile(fname);
多种格式支持 • 支持大部分图像格式 • JPEG • GIF • PNG • TIFF • … • 可以方便地在不同格式间转换
格式转换 • 例12 GIF转换成JPEG string fname = "c:\\globe.gif"; bmp = new Bitmap(Image.FromFile(fname)); bmp.Save("c:\\globe.jpg", ImageFormat.Jpeg);
图像的显示 • 使用Graphics对象的DrawImage方法 • 该方法有多个重载版本,用于对图像的大小、位置等进行控制 按实际大小绘制 Graphics g = panel1.CreateGraphics(); g.DrawImage(bmp,0,0);
指定绘制区域 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);
图像镜像 指定定点法 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);
改变图像的像素值 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 } }