65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 .NET Framework 绘制图形入门指南

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (29投票s)

2009年8月22日

CPOL

7分钟阅读

viewsIcon

139994

一份帮助初学者入门图形绘制的指南。

引言

不可否认,Windows Presentation Foundation (WPF) 已经确立了其在图形等方面的强大技术地位。但这并不意味着初学者无法从 .NET Framework 2.0 提供的图形绘制功能中受益。在 .NET 中,图形绘制始于线条和形状的绘制,然后可以继续处理图像和格式化文本。绘制始于 System.Drawing.Graphics 类。要创建实例,通常需要调用控件的 CreateGraphics 方法。或者,如果您想将图片保存为文件,也可以创建一个基于 Image 对象的 Graphics 对象。一旦创建了 Graphics 对象,您就可以使用许多方法来执行绘制操作。

  • Clear:清除整个表面并用颜色填充。
  • DrawEllipse:绘制由指定的坐标对、高度和宽度定义的边界矩形所定义的椭圆或圆形。
  • DrawIconDrawUnstretched:在指定坐标处绘制由指定图标表示的图像,可以选择是否缩放图标。
  • DrawImage:在指定位置绘制指定的 Image 对象。
  • DrawLine:绘制连接由坐标对定义的两个点的线段。
  • DrawLines:绘制连接一组 Point 结构的连续线段。
  • DrawPath:绘制一系列连接的线条和曲线。
  • DrawPie:绘制由指定的坐标对、宽度、高度以及两条半径线定义的椭圆所确定的扇形。
  • DrawPolygon:绘制一个具有三个或更多边的形状,该形状由一组 Point 结构定义。
  • DrawRectangle:绘制由指定的坐标对、宽度和高度定义的矩形或正方形。
  • DrawString:在指定位置使用指定的 BrushFont 对象绘制指定的文本字符串。

要使用这些方法中的任何一种,您都必须提供 Pen 类的实例。通常,您需要指定 Pen 类的颜色和像素宽度。例如,以下代码从左上角 (1,1) 开始绘制一条 7 像素宽的红色直线到窗体中间附近的点 (100, 100),如下图所示。

1.JPG

要运行此代码,请创建一个 Windows Forms 应用程序,并将代码添加到在窗体的 Paint 事件期间运行的方法中。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }
    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Resize += new System.EventHandler(this.Form1_Resize);
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }
    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = this.CreateGraphics();
        // Make a big red pen.
        Pen p= new Pen(Color.Red, 7);
         g.DrawLine(p, 1, 1, 100, 100);
    }

    private void Form1_Resize(object sender, System.EventArgs e)
    {
    }
}

同样,以下代码绘制一个带有 60 度角的蓝色扇形,如下所示。

2.JPG

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = this.CreateGraphics();
        Pen p = new Pen(Color.Blue, 3);
        g.DrawPie(p, 1, 1, 100, 100, -30, 60);
    }
}

GDI+

GDI 代表图形设备接口 (Graphical Device Interface),GDI+ 库包含允许您完成各种渲染操作的类:渲染线条、曲线、渐变、显示图像…… GDI+ 还允许您绘制诸如贝塞尔曲线之类的几何形状。同样,我们通过调用 ControlForm 类的 CreateGraphics 方法来获取 System.Drawing.Graphics 类的实例。重要的是,一旦通过调用 CreateGraphic( ) 获取了 Graphics 类实例,应尽快调用其 Dispose( ) 方法。

System.Drawing.Pen 类

正如我们所见,正如艺术家需要一支笔来绘制曲线一样,Graphics 类的各种方法用于绘制线条、曲线或形状的轮廓;我们只需要一个 System.Drawing.Pen 的实例。下面是绘制贝塞尔曲线的代码。您可以使用 Pen 类的 Width 属性指定笔触的粗细。此外,您可以使用 Pen 类的 DashStyle 属性指示笔触是实线、虚线还是点线。您还可以使用 Pen 类的 StartCapEndCap 属性指定笔触末端的绘制类型。

3.JPG

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(8, 17);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        using ( Graphics g = CreateGraphics() )
        {
            Pen pen = new Pen( Color.Black);
            pen.Width = 5;
            pen.DashStyle = DashStyle.Dash;
            pen.StartCap = LineCap.RoundAnchor;
            pen.EndCap = LineCap.ArrowAnchor;
            g.DrawBezier( pen, new Point(10, 30), new Point(30, 200), 
                          new Point(50, -100), new Point(70, 100));
        }
    }
}

使用图像

Image 和 Bitmap 类

System.Drawing.Image 抽象类使您可以创建、加载、修改和保存图像,例如 BMP 文件、JPG 文件和 TIFF 文件。Image 类是 abstract 的,但您可以使用 Image.FromFile(接受图像文件的路径作为参数)和 Image.FromStream(接受 System.IO.Stream 对象作为参数)来创建该类的实例。要在窗体中显示保存到磁盘的图像(或作为窗体或控件的背景),请使用 Graphics.DrawImage( ) 方法。以下是一个保存到我的桌面的图像示例(在 Vista 终端上,因此路径为 c:\users\dave\desktop\image.jpg)。

4.JPG

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Bitmap bm = new Bitmap(@"C:\users\dave\desktop\imageA.jpg");
        Graphics g = this.CreateGraphics();
        g.DrawImage(bm, 1, 1, this.Width, this.Height);
    }
}

如何创建和保存图片

要创建一张新的空白图片,请使用不要求现有图像的构造函数之一来创建 Bitmap 类的实例。然后,您可以使用 Bitmap.SetPixel 方法对其进行编辑,或者可以调用 Graphics.FromImage 并使用 Graphics 绘制方法来编辑图像。要保存图片,请调用 Bitmap.Save。下面的代码创建了一个 600x600 的空白 Bitmap,创建了一个基于该 BitmapGraphics 对象,使用 Graphics.FillPolygonGraphics.DrawPolygon 方法在 Bitmap 中绘制一个形状,然后将其保存到当前目录(.NET Framework 2.0 目录)中名为 bm.jpg 的文件中。与上面的代码类似,尽管许多部分是重复的,但它将在控制台命令行上运行。它需要 System.Drawing2DSystem.Drawing.Imaging 命名空间。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }
    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }
    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }
    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Bitmap bm = new Bitmap(600, 600);  
        Graphics g = Graphics.FromImage(bm);
        Brush b = new LinearGradientBrush(new Point(1,1), 
                  new Point(600, 600), Color.White, Color.Red);
        Point[] points = new Point[] { new Point(77, 500), new Point(590, 100), 
                         new Point(250, 590), new Point(300, 410)};
        g.FillPolygon(b, points);
        bm.Save("bm.jpg", ImageFormat.Jpeg);
    }
}

此代码的编写方式将使其编译并执行以输出一个简单的窗体。但是,如果您键入“bm.jpg”,您会发现您创建的文件实际上已保存为 JPEG 文件。下面显示的尺寸已被缩小。

5.jpg

如何使用图标

图标是特定大小的透明位图,Windows 使用它们来传达状态。.NET Framework 通过 SystemIcons 类的属性提供了标准的 40x40 系统图标。添加图标的最简单方法是调用 Graphics.DrawIcon 方法。

6.JPG

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = this.CreateGraphics();
        g.DrawIcon(SystemIcons.Question, 40, 40);
    }
}

当您厌倦了在图形领域有所作为时

图形应用程序可以具有功能性,但这需要我们关注 Control 类的一些核心事件。

  • ClickDoubleClickControl 类定义了许多响应鼠标输入的事件。
  • MouseEnterMouseLeaveMouseDownMouseUpMouseMoveMouseHoverMouseWheel
  • KeyPressKeyUpKeyDownControl 类定义了许多响应键盘输入的事件。

此应用程序旨在展示 Windows Forms 如何响应标准输入。在命令行上运行它。它会为按下的每个键弹出一个对话框,并给出每个鼠标位置的坐标。它还将为每种类型的鼠标点击或按键输出一个消息框。我们首先构建一个新的 Form 类(我们已经做了——MainForm),将窗体的初始大小设置为任意尺寸,并覆盖 Dispose() 方法。为了在窗体顶部显示坐标,必须建立 Rectangle 的边界。

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
          public class MainForm : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;
                         public MainForm()
    {
        Top = 100;
        Left = 75;
        Height = 100;
        Width = 500;

        MessageBox.Show(Bounds.ToString(), "Current rect");

        // Add delegates for mouse & keyboard events.
        this.MouseUp += new MouseEventHandler(OnMouseUp);
        this.MouseMove += new MouseEventHandler(OnMouseMove);
        this.KeyUp += new KeyEventHandler(OnKeyUp);
        InitializeComponent();
        CenterToScreen();
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
        MessageBox.Show("Disposing this Form");
    }

    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        this.Size = new System.Drawing.Size(300,300);
        this.Text = "Form1";
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    protected void OnMouseUp(object sender, MouseEventArgs e)
    {
        // Which mouse button was clicked?
        if(e.Button == MouseButtons.Left)
            MessageBox.Show("Left click!");
        else if(e.Button == MouseButtons.Right)
            MessageBox.Show("Right click!");
        else if(e.Button == MouseButtons.Middle)
            MessageBox.Show("Middle click!");
    }

    protected void OnMouseMove(object sender, MouseEventArgs e)
    {
        this.Text = "Current Pos: (" + e.X + ", " + e.Y + ")";
    }

    public void OnKeyUp(object sender, KeyEventArgs e)
    {
        MessageBox.Show(e.KeyCode.ToString(), "Key Pressed!");
    }
}

在命令行上运行此代码。键入“type con > ControlApp.cs”,然后将代码粘贴到控制台,然后按 Ctrl-Z。使用 /target:winexe 标志并提供 /reference:System.dll。代码运行后,我们就可以看到如何使用图形了。更重要的是,我们现在可以看到图形应用程序如何响应标准输入。例如,假设您必须在标准 Paint 事件处理程序的范围之外渲染某个图像——您想在鼠标单击的 (x, y) 位置绘制一个小圆。首先要做的就是获取一个有效的 Graphics 对象,该对象可以通过静态 Graphics.FromHwnd( ) 方法获得。请注意,我们将当前句柄作为唯一参数传递,并注意 Handle 属性是从 Control 类继承的。这应该是合理的,但与 MouseUp 逻辑结合并添加一个新点到内部 Point 对象集合,然后调用 Invalidate( )(关闭窗口并清除绘制的点)一起使用,效果会更好吗?

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class MainForm : System.Windows.Forms.Form
{
    
    private ArrayList myPts = new ArrayList();

    public MainForm()
    {
        
        InitializeComponent();
        CenterToScreen();
        this.Text = "Basic Paint Form (click on me)";
    }

    public void MyPaintHandler(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
    }

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Form1";
        this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MainForm_MouseDown);
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        // Grab a new Graphics object.
        Graphics g = Graphics.FromHwnd(this.Handle);

        // Now draw a 10*10 circle at mouse click.
        // g.DrawEllipse(new Pen(Color.Green), e.X, e.Y, 10, 10);
                              // Add to points collection.
        myPts.Add(new Point(e.X, e.Y));
        Invalidate(); // means close window
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.DrawString("Hello GDI+", new Font("Times New Roman", 20), 
        new SolidBrush(Color.Black), 0, 0);
                                        foreach(Point p in myPts)
        g.DrawEllipse(new Pen(Color.Green), p.X, p.Y, 10, 10);
    }
}

7.JPG

显示的圆是鼠标在指定位置单击的结果。因此,假设我们有三个 JPEG 图像。我们想单击其中一个,并在窗体顶部识别它。考虑这段代码。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class Form1 : System.Windows.Forms.Form
{
    private System.ComponentModel.Container components;

    // The images.
    private Image bMapImageA;
    private Image bMapImageB;
    private Image bMapImageC;

    // Rects for the images.
    private Rectangle rectA = new Rectangle(10, 10, 90, 90);
    private Rectangle rectB = new Rectangle(10, 110, 90, 90);
    private Rectangle rectC = new Rectangle(10, 210, 90, 90);

    // A polygon region.
    GraphicsPath myPath = new GraphicsPath();

    // Did they click on an image?
    private bool isImageClicked = false;
    private int imageClicked;

    public Form1()
    {
        InitializeComponent();

        // Fill the images with bitmaps.
        bMapImageA = new Bitmap(@"c:\users\dave\desktop\imageA.jpg");
        bMapImageB = new Bitmap(@"c:\users\dave\desktop\imageB.jpg");
        bMapImageC = new Bitmap(@"c:\users\dave\desktop\imageC.jpg");

        // Create an interesting region.
        myPath.StartFigure();
        myPath.AddLine(new Point(150, 10), new Point(120, 150));
        myPath.AddArc(200, 200, 100, 100, 0, 90);
        Point point1 = new Point(250, 250);
        Point point2 = new Point(350, 275);
        Point point3 = new Point(350, 325);
        Point point4 = new Point(250, 350);
        Point[] points = {point1, point2, point3, point4};
        myPath.AddCurve(points);
        myPath.CloseFigure();
        CenterToScreen();
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 11);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Form1";
        this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseUp);
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
    }

    [STAThread]
    static void Main() 
    {
        Application.Run(new Form1());
    }

    private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        // Get (x, y) of mouse click.
        Point mousePt = new Point(e.X, e.Y);

        // See if the mouse is anywhere in the 3 regions...
        if(rectA.Contains(mousePt))
        {
            isImageClicked = true;
            imageClicked = 0;
            this.Text = "You clicked image A";
        }
        else if(rectB.Contains(mousePt))
        {
            isImageClicked = true;
            imageClicked = 1;
            this.Text = "You clicked image B";
        }
        else if(rectC.Contains(mousePt))
        {
            isImageClicked = true;
            imageClicked = 2;
            this.Text = "You clicked image C";
        }
        else if(myPath.IsVisible(mousePt))
        {
            isImageClicked = true;
            imageClicked = 3;
            this.Text = "You clicked the strange shape...";
        }
        else    // Not in any shape, set defaults.
        {
            isImageClicked = false;
            this.Text = "Images";
        }
            
        // Redraw the client area.
        Invalidate();
    }

    private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = e.Graphics;

        // Render all three images.
        g.DrawImage(bMapImageA, rectA);
        g.DrawImage(bMapImageB, rectB);
        g.DrawImage(bMapImageC, rectC);

        // Draw the graphics path.
        g.FillPath(Brushes.AliceBlue, myPath);

        // Draw outline (if clicked...)
        if(isImageClicked == true)
        {
            Pen outline = new Pen(Color.Red, 5);

            switch(imageClicked)
            {
                case 0:
                    g.DrawRectangle(outline, rectA);
                    break;
                
                case 1:
                    g.DrawRectangle(outline, rectB);
                    break;
                
                case 2:
                    g.DrawRectangle(outline, rectC);
                    break;

                case 3:
                    g.DrawPath(outline, myPath);
                    break;

                default:
                    break;
            }
        }
    }
}

那么,我们得到了什么?

8.JPG

单击图像,并在窗体顶部识别它。功能不强,但肯定可以扩展。回看代码,注意 Point 结构的数组以及图像的文件路径。

动画和双缓冲

要创建动画,通过每秒显示几十帧不同的帧,请使用 System.Windows.Forms.Timer 类的实例,该类将负责由窗口线程定期调用某个方法。以下代码演示了如何创建一个动画,该动画表示一个在窗口中央旋转的正方形。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

public partial class AnimForm : Form {
    private float angle;
    private Timer timer = new Timer();
    private BufferedGraphics bufferedGraphics;

    public AnimForm() {
        BufferedGraphicsContext context = BufferedGraphicsManager.Current;
        context.MaximumBuffer = new Size( this.Width + 1, this.Height + 1 );
        bufferedGraphics = context.Allocate( this.CreateGraphics(),
        new Rectangle( 0, 0, this.Width, this.Height) );
        timer.Enabled = true;
        timer.Tick += OnTimer;
        timer.Interval = 20; // 50 images per second.
        timer.Start();
    }

    private void OnTimer( object sender, System.EventArgs e ) {
        angle ++;
        if (angle > 359)
            angle = 0;
        Graphics g = bufferedGraphics.Graphics;
        g.Clear( Color.Black );
        Matrix matrix = new Matrix();
        matrix.Rotate( angle, MatrixOrder.Append );
        matrix.Translate( this.ClientSize.Width / 2, 
            this.ClientSize.Height/ 2, MatrixOrder.Append );
        g.Transform = matrix;
        g.FillRectangle( Brushes.Azure, -100, -100, 200, 200 );
        bufferedGraphics.Render( Graphics.FromHwnd( this.Handle ) );
    }

    [System.STAThread]
    public static void Main() {
        Application.Run( new AnimForm() );
    }
}
© . All rights reserved.