GDI是Graphics Device Interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
在Windows操作系统下,绝大多数具备图形界面的应用程序都离不开GDI,我们利用GDI所提供的众多函数就可以方便的在屏幕、打印机及其它输出设备上输出图形、文本等。GDI的出现使程序员无需要关心硬件设备及设备驱动,就可以将应用程序的输出转化为硬件设备上的输出,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。
GDI+是新一代的二维图形接口,它完全面向对象。GDI+提供了多种画笔、画刷、图像等图形对象,此外还包括一些新的绘图功能,如Alpha混色、渐变色、纹理、消除锯齿以及使用包括位图在内的多种图像格式。如果要设计.NET Franework图形应用程序,就必须使用GDI+。
1.GDI+
GDI+是GDI的改进产品,是.NET Framework的绘图技术,可将应用程序和绘图硬件分离,让我们能够编写与设备无关的应用程序。我们可以调用GDI+类所提供的方法,然后这些方法会适当地调用特定的设备驱动程序,完成绘图。
2.GDI+绘图命名空间
用户所使用的GDI+函数都保存在System.Drawing.dll程序集中。在C#的图形编程中,最常使用的命名空间是System.Drawing ,该命名空间提供了对GDI+基本图形功能的访问,其中一些子命名空间提供了更高级的功能。
System.Drawing命名空间中的常用类:
在绘图过程中,经常会遇到坐标系的问题。窗体、控件都包含坐标,通常的情况是二维图形绘制,即具有X和Y坐标。默认情况下,X坐标代表从绘图区左边边缘(Left)到某一点的距离,Y坐标代表从绘图区上边边缘(Top)到某一点的距离。
(1)坐标原点:在窗体或控件的左上角,坐标为(0,0)。
(2)正方向:X轴正方向为水平向右,Y轴正方向为垂直向下。
(3) 单位:在设置时,一般以像素为单位,像素是用来计算数码影像的一种单位。对显示器而言,像素是指屏幕上的亮点,即显示器能分辨的最少单元。每个像素都有一个坐标点与之对应。
使用GDI+创建图形图像时,首先需要画板,即在哪里画图。Graphics类封装了一个GDI+绘图界面,提供将对象绘制到显示设备的方法。在C#中可以通过Graphics类创建图形对象,即创建了画板。
Graphics类不能直接实例化。创建图形对象的方法有3种:
(1) 利用窗体或控件的Paint事件的参数PaintEventArgs
当响应窗体或控件的Paint事件时,传回的事件参数PaintEventArgs中包含着窗体或控件的Graphics对象,可以在其上进行绘图工作。
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
//声明一个Graphics对象g
}
(2) 使用窗体或控件的CreateGraphics方法
窗体或控件都有一个CreateGraphics方法,通过该方法可以在程序中生成此窗体或控件的Graphics对象,这种方法一般用于对象已经存在的情况下。
Graphics g;
g = this.CreateGraphics();
(3)使用Iamge的派生类创建Graphics对象
使用Image的任何派生类均可以生成相应的Graphics对象。这种方法一般适用于在C#中对图像进行处理的场合,如:
Bitmap b = new Bitmap("mybmp.bmp");
Graphics g = Graphics.FromImage(b);
有了画板,总得有绘图工具。绘图工具有多种,如铅笔用来画线条,画刷用于封闭图形的填充。.在C#中可以用Pen、Brush、Color类实现画线条、填充和选用颜料等功能。
Pen类可以设置笔的颜色,线条的粗细和线条的样式(实线、虚线)等。笔是绘图的工具,Graphics对象是绘图的场所,这样,就可以在允许的界面上绘制各种图形。
1. Pen对象的创建
Pen类的构造函数有4个,使用方法如下:
(1)创建某一颜色的Pen对象
Public Pen(Color)
(2)创建某一刷子样式的Pen对象
Public Pen(Brush)
(3)创建某一刷子样式并具有相应宽度的的Pen对象
Public Pen(Brush,float)
(4)创建某一颜色和相应宽度的Pen对象
Public Pen(Color,float)
【例9-1】使用图形与画笔类直接在窗体上绘制各种基本形状。
1.画直线
画直线可以使用Graphics的DrawLine方法,该方法主要有如下两种格式。
格式1:
public void DrawLine(Pen pen,int x1,int y1,int x2,int y2);
功能:在由(x1,y1)和(x2,y2)指定的点之间画一条直线。
说明:参数pen为画笔,参数x1和y1为所画直线起始点的横坐标和纵坐标,参数x2和y2为所画直线终点的横坐标和纵坐标。
格式2:
public void DrawLine(Pen pen,Point pt1,Point pt2);
功能:在pt1和pt2指定的两个点之间画一条直线。
说明:参数pen为画笔,参数pt1是Point结构的数据,表示所画直线的起始点,参数pt2也是Point结构的数据,表示所画直线的终点。
例如:
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics(); //生成图形对象
Pen p = new Pen(Color.Blue,5); //生成画笔,蓝色,5个像素
g.DrawLine(p, 1,1,30,30); //画线
Point pt1=new Point(1,30); //生成起点
Point pt2=new Point(30,1); //生成终点
g.DrawLine(p, pt1, pt2); //画线
p.Dispose(); //释放资源
g.Dispose();
}
执行上述代码,窗体上将画出两条交叉的直线。
2.画矩形
画矩形可以使用Graphics的DrawRectangle方法,该方法主要有如下两种格式。
格式1 :
public void DrawRectangle(Pen pen,int x1,int y1,int width,int height);
功能:绘制一个由左上角坐标、宽度和高度指定的矩形。
说明:参数pen为画笔,参数x和y为所画矩形左上角的横坐标和纵坐标,参数width和height为所画矩形的宽度和高度。
格式2:
public void DrawRectangle(Pen pen,Rectangle rect);
功能:绘制一个矩形。
说明:参数pen为画笔,参数rect为要绘制矩形的Rectangle结构。
例如:
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics(); // 生成图形对象
Pen p = new Pen(Color.Blue,2); //生成画笔
g.DrawRectangle(p, 5, 5,80, 40); //画矩形
Rectangle rect = new Rectangle(85, 15, 140, 50);
//生成矩形边界
g.DrawRectangle(p, rect); //画矩形
p.Dispose();
g.Dispose();
}
执行上述代码,窗体上将画出2个矩形。
3.画椭圆
使用Graphics对象的DrawEllipse方法可以绘制椭圆或圆,绘制椭圆的常用格式如下。
格式1:
public void DrawEllipse(Pen pen,int x1,int y1,int width,int height);
功能:绘制一个由由边框(该边框由一对坐标、高度和宽度指定)定义的椭圆。
说明:参数pen为画笔,参数x和y分别定义椭圆外接边框的左上角的横坐标和纵坐标,参数width定义椭圆的边框的宽度,参数height定义椭圆的边框的高度。当高度和宽度相同时,画出的是圆。
格式2:
public void DrawEllipse(Pen pen,Rectangle rect);
功能:绘制边界由rect指定的椭圆。
说明:参数pen为画笔,参数rect为Rectangle结构型数据,它定义了椭圆的外接矩形。
例如:
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics(); // 生成图形对象
Pen p = new Pen(Color.Blue,2); //生成画笔
g.DrawEllipse(p, 1, 1,80, 40); //画椭圆
Rectangle rect = new Rectangle(85, 1, 165, 40);
//生成矩形边界
g.DrawEllipse(p, rect); //画椭圆
p.Dispose();
g.Dispose();
}
Brush类(画刷),用于填充图形。该类是一个抽象基类,不能直接实例化,可以通过派生类设置笔刷的样式、颜色及线条的粗细。这里所谓的区域即在什么范围内使用笔刷。
【例9-2】在窗体上为各种形状填充不同的颜色。 本例的目标是使用图形与画刷类为窗体上绘制的基本形状填充颜色。
对于基本形状的绘制,我们可以从图形类中提供的方法中找到解决方案,如三角形为三条相互相连的直线,心形为几个半圆形组合,关键问题是找准其中的连接点位置。但一些数学曲线的处理就比较繁琐,不是标准的形状组合,需要两点一线逐一绘制,下面以一些常用曲线及图表为例进行介绍。
【例9-3】绘制正弦曲线y=sin(x)。
本例的目标是掌握绘制曲线的基本要领。可以在任意窗体或控件上找到各相关点,计算绘制曲线,以正弦曲线为例,首先应找到坐标原点,然后找到每一个曲线上对应点的坐标,在两点之间画一条直线,如此反复直到曲线终点
【例9-4】按百分比绘制饼图。
本实例的目标是掌握绘制统计图形的基本要领。饼图可以直接使用类库中的方法填充图形,不同之处在于统计类图形需和数据关联,如何获取数据并按不同数据绘制不同比例的饼图是实现的关键。