C#-gdi画图,双缓冲画图,Paint事件的触发---ShinePans

在使用gdi技术画图时,有时会发现图形线条不够流畅,或者在改变窗口大小时会闪烁不断的现象.(Use DoubleBuffer to solve it!)

                                                                                                                                                                                                                                     

1.线条不流畅:窗口在重绘时自身重绘与图形重绘之间存在时间差,导致二者图像显示不协调

2.改变窗口大小不流畅:重绘时自身背景颜色与图形颜色频繁交替,造成视觉上的闪烁

      以下,用四个图形样例解决问题 :贝塞尔曲线,圆形,矩形,不规则图形

 

 思路:首先用Bitmap类的构造方法创建一个位图实例,然后通过调用Graphics类FromImage方法创建画布对象,最后调用Grapgics类的DrawImage方法来实如今窗口上绘制图形.

public Bitmap(int width,int height); //width 定义位图的宽度  height 定义位图的高度

Bitmap lacalBitmap =new Bitmap(CilentRectangle.Width,CilentRectangle.Height); //创建一个与窗口工作区大小同样的位图实例


public static Graphics FromImage(Image image);// image:Image类的子类的实例引用 

Bitmap localBitmap=new Bitmap(CilentRectangle.Width,CilentRectangle.Height) //创建位图实例


public void DrawImage(Image image,int x,int y);    // image:要绘制的图像  x:绘制的图像的左上角 x坐标 y:左上角y坐标

Graphics g=e.Graphics;//获取窗口画布

g.DrawImage(localBitmap,0,0);  //在窗口中绘制出内存中的图像



实现:因为Paint被 .net隐藏,我们须要在窗口代码中加上自己的Paint事件中绘制窗口

            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

 private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(388, 325);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.Text = "双缓冲技术画图";
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

            this.ResumeLayout(false);
        }

 

this.Paint+=new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);


源码:
                                                                                                                                                                                                                                                                                                                   
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace DoubleBuffer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Bitmap localBitmap = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
            //创建位图实例
            Graphics bitmapGraphics = Graphics.FromImage(localBitmap);
            bitmapGraphics.Clear(BackColor);
            bitmapGraphics.SmoothingMode = SmoothingMode.AntiAlias;
            PaintImage(bitmapGraphics);
            Graphics g = e.Graphics;//获取窗口画布
            g.DrawImage(localBitmap, 0, 0); //在窗口的画布中绘画出内存中的图像
            bitmapGraphics.Dispose();
            localBitmap.Dispose();
            g.Dispose();
        }
        private void PaintImage(Graphics g)
        {
            //画图
            GraphicsPath path = new GraphicsPath(new Point[]{ new Point(100,60),new Point(350,200),new Point(105,225),new Point(190,ClientRectangle.Bottom),
                new Point(50,ClientRectangle.Bottom),new Point(50,180)}, new byte[]{
                    (byte)PathPointType.Start,
                    (byte)PathPointType.Bezier,
                    (byte)PathPointType.Bezier,
                    (byte)PathPointType.Bezier,
                    (byte)PathPointType.Line,
                    (byte)PathPointType.Line});
            PathGradientBrush pgb = new PathGradientBrush(path);
            pgb.SurroundColors = new Color[] { Color.Green, Color.Yellow, Color.Red, Color.Blue, Color.Orange, Color.LightBlue };
            g.FillPath(pgb, path);
            g.DrawString("双缓冲画图", new Font("宋体", 18, FontStyle.Bold), new SolidBrush(Color.Red), new PointF(110, 20));
            g.DrawBeziers(new Pen(new SolidBrush(Color.Green),2),new Point[] {new Point(120,100),new Point(120,120),new Point(120,100),new Point(120,150)});
            g.DrawArc(new Pen(new SolidBrush(Color.Blue), 5), new Rectangle(new Point(120, 170), new Size(60, 60)), 0, 360);
            g.DrawRectangle(new Pen(new SolidBrush(Color.Orange), 3), new Rectangle(new Point(240, 260), new Size(90, 50)));
        }

     
    }
}

Form1设计:
namespace DoubleBuffer
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理全部正在使用的资源。
        /// </summary>
        /// <param name="disposing">假设应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗口设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器改动此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(388, 325);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.Text = "双缓冲技术画图";
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
            this.ResumeLayout(false);

        }

        #endregion
    }
}


Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace DoubleBuffer
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}




当变化窗口时,会导致图像出现变形,可把窗口属性中的ResizeReDrae 设置为 true


                                                                                                                  =                                                               

posted @ 2014-09-04 20:44  mfrbuaa  阅读(1067)  评论(0编辑  收藏  举报