编写图形程序时需要使用GDI(图形设备接口Graphics Device Interface),从程序设计的角度看,GDI包括两个部分:GDI对象和GDI函数。 GDI对象定义了GDI函数使用的工具和环境变量,GDI函数对象绘制各种图形。在C#中,进行图形程序编写时用到的都是GDI+版本,是GDI的进一步扩展,它使我们变成更加方便。
GDI+是微软提供的新的图形设备接口,通过托管代码的类来展现。GDI+主要提供了三类服务:
二维矢量图形
图像处理
文字显示
GDI+比GDI的优越性主要展现在2个方面:
扩展了新功能
变成更加简易灵活
Graphics类封装一个GDI+绘图页面,提供将对象绘制到显示设备的方法,与特定的设备上下文关联。所有的画图方法都被包括在Graphics类中,在绘制任何对象时,我们首先要创建一个Ggraphics实例,这个实例相当于创建了一块画布,有了画布才可以使用各种画图方法绘图。 绘图程序的设计一般分为两个步骤:
(一)创建Graphics对象; (二)使用创建的Graphics对象的方法绘图、显示文本或处理图像。
利用Paint事件中的PaintEventArgs在窗体或控件的Paint事件中接收对图像对象的引用。在为控件创建绘制代码时,通常用此方法。
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; }
调用控件或窗体的CreatGraphics方法 调用控件或窗体的CreateGraphics方法获取对象的引用,创建Graphics的实例。如果想在已存在的窗体或控件上画图,通常使用此方法创建实例。
//1.创建Graphics对象实际上就是创建一块画布, //所以要确定这个画布所在的位置,以哪个对象为主创建画布 Graphics g = this.CreateGraphics();
调用Graphics类的FromImage()方法。在需要更改已存在的图像时,通常用此方法。
Image img = Image.FromFile("g1.jpg"); Graphics g1 = Graphics.FromImage(img);
创建了Graphics类的对象引用后,就可以利用该对象的成员绘制各种各样的图形,下表列出了Graphics类的常用方法成员。
方法名称 | 说明 |
---|---|
DrawArc | 画弧形 |
DrawBezier | 画立体的贝尔赛曲线 |
DrawClosedCurve | 画闭合曲线 |
DrawCurve | 画曲线 |
DrawEllipse | 画椭圆 |
DrawImage | 画图像 |
DrawLine | 画线 |
DrawPie | 画饼状图 |
DrawPolygon | 画多边形 |
DrawRectangle | 画矩形 |
DrawString | 绘制文本 |
FillEllipse | 填充椭圆 |
FillPath | 填充路径 |
FillPie | 填充饼图 |
FillRectangle | 填充矩形 |
FillRegion | 填充区域 |
在.NET中,GDI+的所有绘图功能都包括在System.Drawing、System.Drawing.Imaging、System.Drawing.Drawing2D和System.Drawing.Text中
在创建了Graphics对象后,就可以用它来画图了,可以画线、填充图形、显示文本等,其中主要用到的画图对象有:
private void button1_Click(object sender, EventArgs e)
{
Graphics graphics = panel1.CreateGraphics(); Pen pen = new Pen(Color.Red,5);
Rectangle rect = new Rectangle(100,100,100,100); graphics.DrawRectangle(pen,rect);
}
当图形画好之后窗体的位置、大小发生更改则最终图形会消失
原因是:winform框架中所有的图形化控件全部都是GDI绘制而成,当控件的位置、大小发生改变时,其实都是经过重新绘 制而成的,但是控件对象在重新绘制的过程中并不会绘制其之后通过其他方式所绘制在其上面的图形
解决:通过图形控件的Paint事件
常用的绘图对象
Pen类用来绘制指定宽度和样式的直线。使用DashStyle属性绘制几种虚线,可以得到各种填充样式(包括纯色和纹理)来 填充Pen绘制的直线。
属性名称 |
描述 |
Alignment |
获得或者设置画笔的对齐方式 |
Brush |
获得或者设置画笔的属性 |
Color |
获得或设置画笔的颜色 |
Width |
获得或设置画笔的宽度 |
封装对颜色的定义,静态方法如下表:
名称 |
描述 |
FromArgb |
从四个8位分量值创建Color对象 |
FromKnowColor |
从指定的预定义颜色创建一个Color对象 |
FromName |
从预定义颜色的指定名称创建一个Color对象 |
定义特定文本格式,包括字体、字号和字形属性。Font类的常用构造函数是public Font(string字体名,float字号,
FontStyle字形),其中字号和字体为可选项和public Font(string字体名,float 字号),其中“字体名”为Font的
FontFamily的字符串表示形式。
Brush类是一个抽象的基类,因此它不能被实例化,我们总是用它的派生类进行实例化一个画刷对象,当我们对图形内部进 行填充操作时就会用到画刷
存储一组整数,共四个,表示一个矩形的位置和大小。矩形结构通常用来在窗体上画矩形,除了利用它的构造函数构造矩形 对象外,还可以使用Rectangle结构的属性成员
名称 |
说明 |
Bottom |
底端坐标 |
Height |
矩形高 |
IsEmpty |
测试矩形宽和高是否为0 |
Left |
矩形左边坐标 |
Location |
矩形的位置 |
Right |
矩形右边坐标 |
Size |
矩形尺寸 |
Y |
矩形左上角顶点Y坐标 |
Top |
矩形顶端坐标 |
Width |
矩形宽 |
用指定坐标初始化Point类的新实例。这个结构很像C++中的Point结构,它描述了一对有序的x,y两个坐标值,其构造函数 为:public Point(int x,int y);其中x为该点的水平位置;y为该点的水垂直位置。
private void button1_Click(object sender, EventArgs e)
{
//网格宽高300
Bitmap bit = new Bitmap(300, 300);
//绘图对象
Graphics g = Graphics.FromImage(bit);
//清除画布,背景为天蓝色
g.Clear(Color.Cyan);
//横线
for(int i = 0; i < 30; i++)
{
g.DrawLine(new Pen(Brushes.Red, 1), 0, i * 20, 300, i * 20);
}
//竖线
for(int i = 0; i < 20; i++)
{
g.DrawLine(new Pen(Brushes.Red, 1), i * 20, 0, i * 20, 300);
}
this.BackgroundImage = bit;
//加边框
g.DrawRectangle(new Pen(Color.Black), 0, 0, bit.Width - 1, bit.Height - 1);
this.BackgroundImageLayout = ImageLayout.None;
}