Graphics对象

创建和使用Graphics对象

用计算机语言编写成的程序是对相关事物和关系的高度抽象和概括。为了更好地理解这一节的内容,我们从绘画这件事情说起。我们的画,可以绘在纸上,布上,墙壁上,木板上,或者电脑屏幕上。用计算机语言来描述绘画这件事情的时候,就要进行抽象,这些纸、布、墙壁、木板、电脑屏幕可以全部抽象成一个表面,即一个可以绘图的表面。

GDI+中有绘图表面的概念,在这里,绘图表面可以是窗体、控件、打印机、预览或者图像。当指定绘图表面是图片框以后,绘图行为将在图片框上发生,而不会画到窗体上去。指起绘图表面是窗体时,绘图行为就在窗体上发生,也不会画在图片框上。但问题是,谁来指定绘图表面呢?想起一个笑话:老鼠们开会,议题是如何对付猫。有鼠提议,给猫脖子上挂个铃铛不就得了。提议近于完美,但问题是谁去给猫脖子上挂铃铛呢?

所以由谁来指定是问题的关键。

,这里是由Graphics.象来指定\"就像GDI中的设备上下文一样,Graphics象与特定的窗口相关联,指定绘图表面。

虽然把Graphics对象与上面的笑话联系在一起不太恰当,但关于谁来指定的问题的确太重要了。所以,这个(Gjrap cs对象太重要了,有人甚至说,术是最重要的。但本人,为如果把,Graphics对象比做纸的话,那还得有笔有墨这画才画得成。说哪个最重要就像讨论先有蛋还是先有鸡一样,不是我们研究的范畴。但不管哪个最重要,用GDI+进行具体的绘图工作以前,必须创建一个Graphics对象的实例却是千真万确的事实。

根据绘图表面的不同,有不同的创建Graphics对象实例的方法。当指定绘图表面为窗体时,下面的代码介绍了创建Graphics对象实例的两种方法。创建实例以后,对于该实例所做的任何绘图行为都作用在窗体上。

【VB.NET】

code.vb.net
Public Class Form1
    Inherits System.Windows.Forms.Form
    '…
    Protected Overrides Sub OnPaint(ByVal text-blue-400">e As PaintEventArgs)
        Dim g As Graphics =text-blue-400">e.Graphics
        '…
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object,_
                ByVal text-blue-400">e As System.EventArgs) Handles Button1.text-blue-400">Click
        Dim g As Graphics = Me.CreateGraphics()
        '…
    End Sub
End Class

【VC#.NET】

code.vc#.net
namespace Graph
{
    public class Forml : System.Windows.Forms.Form
{
        //…
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g= e.Graphics;
            //…
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Graphics g= this.CreateGraphics();
            //…
        }
    }
}

第1种方法假设当前过程是绘制窗体的OnPaint方法,则可以直接从该方法的参数e中获得 raphic对象的实例;第和方法假设通过单击一个命令按钮来实现在窗体上绘图,此时调用Form1类的CreateGraphics方法创建Graphics对象实例。

如果指定绘图表面为控件,如图后框,则必须通过调用该控件的CreateGraphics方法来个建Graphics对象实 。下面的语句个建止片框控Pictre:Box1(rictre:Box)的G'raphics欢象实例。

【VB.NET)】

code.vb.net
Dim g As Graphics = Picture Box1.CreateGraphics()

(VC#.NET】

code.vc#.net
Graphics g= pictureBox1.CreateGraphics();

创建Graphics对象的实例以后,就有了画布,但还要有笔和墨。在GDI+中,代表笔的Pen 对象和代表墨的Color对象是独立于代表纸的Graphics对象的,将在后面的小节中进行介绍。但关于Graphics对象的内容还远远没完。试想,我们讲书法要讲究章法,绘画要讲究构图,其实就隐含了坐标参照系的概念;写生素描要涉及到比例问题;用计算机绘图,还要提供组成任何几何图形所需要的基本图形元素如直线段、椭圆、椭圆弧、曲线、区域、文本等的绘制方法,这些都由Graphics对象提供。表3-1中示出了Graphics对象的部分属性,表3-2中示出了Graphics对象的部分方法。表中的内容将在后续章节中陆续用到,届时再进行详细说明。

表3-1至表1-3列出了Graphics对象的部分属性和方法。

Document Image
\[\]
Document Image
\[\]
Document Image
\[\]

下面举一个例子,介绍Graphics.象的创建和使用。该示例在窗体上放置一个图片框PictureBox1(pictureBox1)和两个命令按钮 Button1(button1)和 Button2(button2),要求重绘窗体时在图片框周围绘一个红色矩形:单击两个命令按钮时分别在窗体和图片框上绘制蓝色椭圆。本例用到了Pen对象、Brushes对象和Color对象。这里暂不做详细介绍,可参见后续章节的内容。

【VB.NET】

code.vb.net
Protected Overrides Sub OnPaint(ByVal text-blue-400">e As PaintEventArgs)
    Dim g As Graphics = text-blue-400">e.Graphics
    Dim x As Single,y As Single
    Dim w As Single,h As Single
    With PictureBox1
        x=.Left-2
        y=.Top -2
        W=.Width+4
        h=.Height+4
    End With
    Dim pen As New Pen(Color.Red, 2)
    g.DrawRectangle(pen,x,y, w,h)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object,
            ByVal text-blue-400">e As System.EventArgs) Handles Button1.text-blue-400">Click
    Dim g As Graphics = Me.CreateGraphics()
    g.FillEllipse(Brushes.Blue, 10, 20, 50,100)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object,_
            ByVal text-blue-400">e As System.EventArgs) Handles Button2.text-blue-400">Click
    Dim g As Graphics = PictureBox .CreateGraphics()
    g.Filllipse(Brushes.Blue, 10, 20, 50,100)
End Sub

【VC#.NET】

code.vc#.net
protected override void OnPaint(PaintEventArgs e)
{
    Graphics g=e.Graphics;
    float x, y,w,h;
    x= pictureBox1.Left- 2;
    y= pictureBox1.Top - 2;
    w= pictureBox1.Width +4;
    h = pictureBox1.Height +4;
    Pen pen=new Pen(Color.Red, 2);
    g.DrawRectangle(pen,x,y, w,h);
}
private void button1_Click(object sender, EventArgs e)
{
    Graphics g= this.CreateGraphics();
    g.Fillipse(Brushes.Blue, 10, 20, 50, 100);
}
private void button2_Click_1(object sender, EventArgs e)
{
    Graphics g= pictureBox1.CreateGraphics();
    g.FillElipse(Brushes.Blue, 10, 20, 50, 100);
}

运行程序,单击两个命令按钮以后窗体显示结果如图3-1所示。

Document Image
\[\]

图3-1创建和使用Graphics对象

Paint事件和OnPaint方法

上一节的例子中我们用到了OnPaint方法,它重写基类的OnPaint方法,用于绘制窗体。在VB6.0中,绘制窗体用的是窗体的Paint事件,每次要求绘制窗体时触发该事件。NET中绘制窗体也可以用Paint事件。如:

【VB.NET】

code.vb.net
Private Sub Form1_Paint(ByVal sender As Object,_
        ByVal text-blue-400">e As PaintEventArgs) Handles MyBase.Paint
    Dim g As Graphics = text-blue-400">e.Graphics
    g.DrawEllipse(Pens.Blue, 50, 50,100, 100)
End Sub

【VC#.NET】

code.vc#.net
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g=e.Graphics;
    g.DrawEllipse(Pens.Blue,50,50,100,100);
}

这样,实现绘制窗体的任务就有两种方法供我们选择,但两种方法是有差别的。用Paint事件绘制窗体时,会调用基类的OnPaint方法,而用重写的OnPaint方法绘制窗体时则不需要调用基类的OnPaint方法。所以,前者的消耗要大一些。