第09章 二维图形图像处理.docx

上传人:b****6 文档编号:6030794 上传时间:2023-01-03 格式:DOCX 页数:47 大小:63.62KB
下载 相关 举报
第09章 二维图形图像处理.docx_第1页
第1页 / 共47页
第09章 二维图形图像处理.docx_第2页
第2页 / 共47页
第09章 二维图形图像处理.docx_第3页
第3页 / 共47页
第09章 二维图形图像处理.docx_第4页
第4页 / 共47页
第09章 二维图形图像处理.docx_第5页
第5页 / 共47页
点击查看更多>>
下载资源
资源描述

第09章 二维图形图像处理.docx

《第09章 二维图形图像处理.docx》由会员分享,可在线阅读,更多相关《第09章 二维图形图像处理.docx(47页珍藏版)》请在冰豆网上搜索。

第09章 二维图形图像处理.docx

第09章二维图形图像处理

第9章二维图形图像处理

本章介绍在C#中如何利用GDI+进行二维图形图像处理。

GDI+是GDI(GraphicsDeviceInterface,图形设备接口)的后续版本,提供了高级图形图像处理功能。

在C#中,可利用GDI+提供的一套托管类编写各种设备无关的图形应用程序,例如游戏、计算机辅助设计、绘图程序等等。

9.1GDI+概述

GDI+是微软在Windows2000以后操作系统中提供的新接口,.NETFramework通过一套部署为托管代码的类来展现提供的图形图像处理功能,这套类被称为GDI+的托管类。

利用GDI+可以轻松实现一般图形图像处理、颜色渐变、透明处理、纹理处理、拉伸和缩放等多种高级功能。

GDI+主要提供了以下三类服务:

1.二维矢量图形:

GDI+提供了构造和绘制基本图形的类。

例如,可以利用Rectangle类构造矩形的位置和大小;利用Pen类提供线条颜色、粗细和线型的信息;利用Brush的扩充类提供如何利用颜色或图案来填充封闭图形和路径的信息;而Graphics类则提供了对图形进行各种处理的方法。

2.图像处理:

由于大多数图像并不是直线和曲线的简单组合,无法直接使用二维矢量图形方式进行处理。

因此,GDI+提供了Bitmap、Image等类,用于显示、操作和保存BMP、JPG、GIF等图像格式。

3.文字显示:

GDI+支持使用各种字体、字号和样式来显示文本。

另外,在GDI+中还提供了许多实用的功能,比如渐变画刷、基样条曲线、Alpha混合、反锯齿处理、矩阵变换、浮动坐标等。

实际上,在托管代码中,我们不需要考虑GDI+内部是如何实现的,直接使用提供的类进行编程就可以了。

所有图形图像处理功能都包含在下面介绍的命名空间下。

1)System.Drawing命名空间

System.Drawing命名空间提供了对GDI+基本图形功能的访问,主要有Graphics类、Bitmap类、从Brush类继承的类、Font类、Icon类、Image类、Pen类和Color类等。

2)System.Drawing.Drawing2D命名空间

System.Drawing.Drawing2D命名空间提供了高级的二维和矢量图形处理功能,主要有:

梯度型画刷、Matrix类(用于定义几何变换)和GraphicsPath类等。

3)System.Drawing.Imaging命名空间

System.Drawing.Imaging命名空间提供了高级图像处理功能。

4)System.Drawing.Text命名空间

System.Drawing.Text命名空间提供了字体和文本排版功能。

9.1.1GDI+使用的坐标系

开发Windows应用程序时,GDI+提供的坐标系为我们提供了很大的方便。

它就如同给设计者一个导航图,使设计者能方便的使用各种图形命令。

1.GDI+坐标系中的基本结构

在GDI+坐标系中,有三种最基本的结构,分别是Point、Size和Rectangle。

1)Point

Point在三种结构中是最简单的,GDI+使用Point表示某个特定位置相对于原点的水平和垂直距离。

许多GDI+函数都是以Point作为参数的。

声明和构造Point的代码示例如下:

Pointp=newPoint(1,1);

2)Size

在GDI+中,Size也表示一个尺寸,它也有两个整型属性来表示水平和垂直距离——Width和Height。

但是Point和Size的含义是不同的,Point是用来说明实体具体位置的,而Size是用来说明实体有多大的。

声明和构造Size代码示例如下:

Sizes=newSize(5,5);

3)Rectangle

Rectangle是用来指定矩形的坐标的,它由一个Point和一个Size组成,其中Point表示矩形左上角,Size表示矩形大小。

声明和构造Rectangle有两种方式:

1)在构造函数中分别指定x坐标、y坐标、宽度和高度。

例如:

Rectangler1=newRectangle(1,2,5,6);

2)在构造函数中指定Point位置和Size结构。

例如:

Pointp=newPoint(1,2);

Sizes=newSize(5,6);

Rectangler2=newRectangle(p,s);

2.GDI+中坐标系的分类

图9-1世界坐标系示意图

GDI+中的坐标系分为三类:

世界坐标系(Worldcoordinates)、设备坐标系(Devicecoordinates)和页面坐标系(Pagecoordinates)。

世界坐标系是用于建立特殊图形世界模型的坐标系,也是在程序中调用方法时传递参数使用的坐标系。

世界坐标系是一种通用的坐标系,可以适用于任何计算机设备。

默认情况下,X轴正方向水平向右,Y轴正方向垂直向下,如图9-1所示。

设备坐标系是指显示设备或打印设备使用的坐标系,它的特点是以设备上的像素点为单位。

对于窗体中的视图而言,设备坐标的原点在窗体绘图区的左上角,x坐标从左向右递增,y坐标自上而下递增。

由于设备的分辨率不同,相同坐标值的物理位置可能不同。

如对于边长为100的正方形,显示器为800×600和1024×768时的大小是不一样的。

页面坐标系指某种映射模式下的一种坐标系。

所谓映射是指将世界坐标系通过某种方式进行的变换。

通俗些说,页面坐标系就是指绘图图面(如窗体或控件)使用的坐标系。

页面坐标系统与设备坐标系统的差异在于X,Y的单位不同:

页面坐标系中的X,Y单位可以任意设定,如英寸、毫米等;而设备坐标系中,只有一种单位,对显示器而言就是像素,对打印机而言就是1/72英寸。

图9-2屏幕坐标示意图

默认情况下,设备坐标和页面坐标是相同的,均使用像素作为度量单位。

图9-2演示了计算机屏幕中坐标的位置情况。

如果将度量单位设置为像素以外的其他单位(例如英寸),则设备坐标和页面坐标就不相同了。

3.不同坐标系的转换

实际上,我们调用GDI+的Graphics对象进行操作时,调用对应的方法时传递给方法的坐标为世界坐标系中的坐标,而在屏幕或者打印机上显示的是设备坐标系中的坐标。

因此,每次输出时,系统都会自动进行两次坐标变换——第一次是从世界坐标向页面坐标的变换,称之为世界变换(worldtransformation);第二次是从页面坐标向设备坐标的变换,称之为页面变换(pagetransformation)。

在程序中,我们也可以通过调用Graphics对象的TranslateTransform方法改变世界变换的原点,通过设置Graphics对象的PageUnit和PageScale属性改变页面变换的度量单位。

除此之外,Graphics类还提供了两个只读属性:

DpiX和DpiY,用于检查显示设备每英寸的水平点数和垂直点数。

【例9-1】

图9-3坐标转换示例

分别调用Graphics对象的世界变换和页面变换,使用英寸作为度量单位,并让坐标系的原点距工作区左边缘0.5英寸、距工作区顶部0.5英寸,然后从(0,0)到(2,2)绘制一条直线。

privatevoidForm1_Paint(objectsender,PaintEventArgse)

{

GraphicsmyGraphics=e.Graphics;

myGraphics.TranslateTransform(0.5F,0.5F);

myGraphics.PageUnit=GraphicsUnit.Inch;

PenmyPen=newPen(Color.Black,1/myGraphics.DpiX);

myGraphics.DrawLine(myPen,0,0,2,2);

}

图9-3为绘制的直线,图中标出的坐标系不是这段代码绘制的,仅是为了观察方便。

如果假定显示设备在水平方向和垂直方向每英寸都有100个像素,则例9-1中直线的起点和终点在三种坐标系中分别具有表9-1所示的坐标值。

表9-1直线在三种坐标系统中的坐标值

世界坐标系统

(0,0)到(0.5,0.5)

页面坐标系统

(0.5,0.5)到(2.5,2.5)

设备坐标系统

(50,50)到(250,250)

9.1.2Graphics类

Graphics类包含在System.Drawing命名空间下,它提供了简单的图形图像处理功能。

在绘制图形图像前,首先必须创建Graphics对象,然后利用这个对象绘制直线、曲线、椭圆等图形图像。

有三种常见的创建Graphics对象的方法。

第一种方法是在窗体或控件的Paint事件中获取Graphics对象。

例如:

privatevoidForm1_Paint(objectsender,System.Windows.Forms.PaintEventArgse)

{

Graphicsg=e.Graphics;

}

在每一个窗体或控件中,都有一个Paint事件,该事件的参数包括了当前窗体或控件的Graphics对象,在为窗体或控件创建绘图代码时,一般使用此方法来获取对图形的引用。

第二种方法是通过当前窗体的CreateGraphics方法,把当前窗体的画笔、字体、颜色作为默认值,获取对Graphics对象的引用。

例如:

Graphicsg;

g=this.CreateGraphics();

……

注意这种对象只有在处理当前Windows窗体消息的过程中有效,如果想在已经存在的窗体或控件中绘图,可以使用此种方法。

第三种方法是从继承自图像的任何对象创建Graphics对象,例如:

BitmapmyBitmap=newBitmap(@"C:

\mytest1\Pics\myPic.bmp");

Graphicsg=Graphics.FromImage(myBitmap);

这个方法适用于需要更改已经存在的图像的情况。

9.1.3颜色

颜色是进行图形操作的基本要素,它封装在System.Drawing.Color结构中。

人眼可以分辨的显示的颜色都是由一定的红、绿、蓝三色光组合而成。

任何一种颜色都可以有四个分量,分别是:

R、G、B、A。

其中:

R:

红色,取值范围0~255,0表示没有红色成分,255为饱和红色;

G:

绿色,取值范围0~255,0表示没有绿色成分,255为饱和绿色;

B:

蓝色,取值范围0~255,0表示没有蓝色成分,255为饱和蓝色;

A:

Alpha值,即透明度,取值范围0~255,0表示完全透明,255表示完全不透明。

在代码中声明颜色的方式常用有两种:

1.调用静态方法Color.FromArgb()指定任意颜色

这种方法有两种常用形式。

第一种形式为直接指定三种颜色,方法原型为:

PublicstaticColorFromArgb(intred,intgreen,intblue)

三个参数分别表示R、G、B三色,Alpha值使用默认值255,即完全不透明。

例如:

Colorred=Color.FromArgb(255,0,0);

Colorgreen=Color.FromArgb(0,255,0);

Colorblue=Color.FromArgb(0,0,0xff);

其中0xff为十六进制表示形式。

第二种形式为四个参数,方法原型为:

PublicstaticColorFromArgb(intalpha,intred,intgreen,intblue)

四个参数分别表示透明度、R、G、B三色值。

2.系统预定义颜色

System.Drawing.Color结构中提供了许多静态属性,每个属性返回一个命名颜色,在Color结构中已经预定义了141种颜色,可以直接使用。

例如:

this.BackColor=Color.White;

9.1.4画笔和画刷

本节介绍Pen类和Brush类,在绘制图形时需要使用画笔和画刷绘制或填充图形、文本和图像。

画笔是Pen类的实例,用于绘制各种直线、空心图形和实心图形等。

画刷是从Brush类派生的任何类的实例,用来填充形状或绘制文本。

1.画笔(Pen)

画笔可用于绘制具有指定宽度和样式的直线、曲线或轮廓形状。

下面的示例说明如何创建一支基本的蓝色画笔:

PenmyPen=newPen(Color.Blue);//创建一支蓝色画笔,宽度默认为1个像素

PenmyPen=newPen(Color.Blue,10.5f);//创建一支宽度为10.5个像素的蓝色画笔

也可以从画刷对象创建画笔对象,例如:

SolidBrushmyBrush=newSolidBrush(Color.Red);//实心画刷,默认宽度为1个像素

PenmyPen=newPen(myBrush);//从现有画刷创建红色画笔

PenmyPen=newPen(myBrush,5);//从现有画刷创建宽度为5个像素的红色画笔

创建画笔后,即可使用它来绘制直线、曲线或空心形状。

还可以修改画笔的各种属性,比如使用Width属性修改画笔的宽度;使用Color属性修改画笔的颜色;使用StartCap和EndCap属性将预设或自定义的形状添加到线条的开始和结尾;使用DashStyle属性指定画笔绘制的虚线样式等。

【例9-2】画笔的用法。

(1)新建一个名为PenExample的Windows应用程序,调整窗体到适当大小。

然后切换到代码方式,添加命名空间引用:

usingSystem.Drawing.Drawing2D;

(2)在窗体的属性中找到Paint事件,双击此事件,添加Form1_Paint事件代码:

privatevoidForm1_Paint(objectsender,PaintEventArgse)

{

//创建Graphics对象

Graphicsg=e.Graphics;

//创建一支黑色的画笔

Penblackpen=newPen(Color.Black,10.0f);

//绘制字符串

g.DrawString("黑色,宽度为10.0",this.Font,Brushes.Black,5,5);

//绘制宽度为10.0f的黑色直线

g.DrawLine(blackpen,newPoint(110,12),newPoint(400,12));

//创建一支红色的画笔

Penredpen=newPen(Color.Red,5.0f);

//绘制字符串

g.DrawString("红色,宽度为5",this.Font,Brushes.Black,5,25);

//绘制宽度为5的红色直线

g.DrawLine(redpen,newPoint(110,30),newPoint(400,30));

//创建一支蓝色的画笔

Penbluepen=newPen(Color.Blue,6);

//定义直线的样式

bluepen.StartCap=LineCap.Flat;

bluepen.EndCap=LineCap.ArrowAnchor;

//绘制字符串

g.DrawString("蓝色箭头线",this.Font,Brushes.Black,5,45);

//绘制宽度为6的蓝色箭头线

g.DrawLine(bluepen,newPoint(110,50),newPoint(400,50));

//再创建一支黑色的画笔

Peniblackpen=newPen(Color.Black,2.0f);

//定义直线的样式

iblackpen.DashStyle=DashStyle.Custom;

iblackpen.DashPattern=newfloat[]{4,4};

iblackpen.EndCap=LineCap.NoAnchor;

//绘制字符串

g.DrawString("自定义虚线",this.Font,Brushes.Black,5,65);

//绘制宽度为2的自定义虚线

g.DrawLine(iblackpen,newPoint(110,70),newPoint(400,70));

//再创建一支红色的画笔

Peniredpen=newPen(Color.Red,2.0f);

//定义直线的样式

iredpen.DashStyle=DashStyle.Dot;

//绘制字符串

g.DrawString("点划线",this.Font,Brushes.Black,5,85);

//绘制宽度为2的点划线

g.DrawLine(iredpen,newPoint(110,90),newPoint(400,90));

}

(3)运行程序,结果如图9-4所示。

图9-4画笔的用法演示

2.画刷(Brush)

画刷是可以与Graphics对象一起使用来创建实心形状和呈现文本的对象。

可以用来填充各种图形形状,如矩形、椭圆、扇形和多边形等。

表9-2列出了几种不同类型的画刷。

表9-2画刷类型

说明

SolidBrush

用纯色填充图形

TextureBrush

用基于光栅的图像(位图、JPG等)填充图形

LinearGradientBrush

用颜色渐变填充图形——颜色渐变是指一种颜色沿着指定方向或在两个指定的(平行)边界线之间逐渐变成另一种颜色

PathGradientBrush

用渐变效果填充图形,渐变的方向是从由路径定义的图形边界指向图形的中心。

这种渐变可以让人想起中学的彩色地图,即用较深的颜色给国土的轮廓着色,而用较浅的颜色给国土的中心着色

HatchBrush

用各种图案填充图形

1)使用SolidBrush类定义画刷

SolidBrush类用于定义单色画刷。

该类可以填充图形,比如矩形、椭圆、多边形和路径。

例9-3演示了如何在窗体中填充一个纯红色的椭圆。

【例9-3】单色画刷演示示例。

图9-5单色画刷示例运行图

(1)新建一个名为SolidBrushExample的Windows应用程序,调整窗体到适当大小。

(2)在窗体的属性中找到Paint事件,双击此事件,添加Form1_Paint事件代码。

privatevoidForm1_Paint(objectsender,PaintEventArgse)

{

Graphicsg=e.Graphics;

SolidBrushmySolidBrush=newSolidBrush(Color.Red);

g.FillEllipse(mySolidBrush,30,30,130,100);

}

(3)运行程序,结果如图9-5所示。

2)使用HatchBrush类填充简单图案

HatchBrush类提供的画刷可以用各种图案填充图形。

通过Hatch类型可以设置影线样式。

在创建影线的画刷时,能设定前景色、背景色和影线样式。

有56种不同的影线样式枚举,该枚举可以参看System.Drawing.Drawing2D.HatchStyle枚举。

例9-4演示了如何创建一个HatchBrush,例子使用垂直影线,白色为前景色,红色为背景色。

【例9-4】填充简单图案示例。

(1)新建一个名为HatchBrushExample的应用程序,调整窗体到适当大小。

然后切换到代码方式,添加命名空间引用:

usingSystem.Drawing.Drawing2D;

(2)在窗体的属性中找到Paint事件,双击此事件,添加Form1_Paint事件代码。

图9-6HatchBrush类示例

privatevoidFom1_Paint(objectsender,PaintEventArgse)

{

Graphicsg=e.Graphics;

HatchBrushmyHatchBrush=

newHatchBrush(HatchStyle.Cross,Color.White,

Color.Red);

g.FillEllipse(myHatchBrush,this.ClientRectangle);

}

(3)运行程序,结果如图9-6所示。

3)使用TextureBrush类填充复杂图像

TextureBrush类使用图像作为填充的样式,它可以使用例如.bmp、.jpg、.png等格式的图像。

初始化一个新的TextureBrush对象需要指定填充的图像。

①TextureBrush类提供了5个重载的构造函数,分别是:

publicTextureBrush(Image)

publicTextureBrush(ImageRectangle)

publicTextureBrush(Image,WrapMode)

publicTextureBrush(Image,Rectangle,ImageAttributes)

publicTextureBrush(Image,WrapMode,Rectangle)

其中,Image用于指定画刷所要填充的图案;Rectangle用于指定图像上用于画刷的矩形区域,其位置不能超越图像的范围;WrapMode枚举成员用于指定如何排布图像,其值见表9-3。

表9-3WrapMode枚举值

WrapMode值

说明

Clamp

完全由绘制对象的边框决定

Tile

平铺

TileFlipX

水平方向翻转并平铺图像

TileFlipY

垂直方向翻转并平铺图像

TileFlipXY

水平和垂直方向翻转并平铺图像

ImageAttributes:

ImageAttributes对象用于指定图像的附加特性参数。

②TextureBrush类有3个属性,如表9-4所示。

表9-4TextureBrush类属性

名称

属性

Image

Image类型,与画刷关联的图像对象

Transform

Matrix类型,画刷的变换矩阵

WrapMode

WrapMode枚举成员,指定图像的排布方式

例9-5说明了如何创建一个TextureBrush,该例使用名为xue.jpg的图像进行填充。

【例9-5】创建TextureBrush示例。

(1)新建一个名为TextureBrushExample的Windows应用程序,调整窗体到适当大小。

(2)鼠标右键单击【解决方案资源管理器】中的项目名,选择【添加】【添加现有项】,在弹出的窗体中选择添加的文件类型为“ImageFiles”,找到需要使用的图片,将其添加到当前项目中,并修改图

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1