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事件中绘制窗口
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);
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
=