Winform 中 BufferedGraphics对象 充许开发者自定义缓冲绘制,该对象比直接使用 Graphics 绘制操作,性能大约提高一倍。
下例将 BufferedGraphics 操作 封装到一个 PictureBox 对象中, 通过 isBufferDraw 控制是否使用缓冲绘制,测试结果如下:
A. isBufferDraw 设置 false ,Graphics 绘制 , 效果如下,每秒 3 帧多一点:
B. isBufferDraw 设置 true ,使用 BufferedGraphics 绘制,每秒 8 帧多一点:
测试代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace BufferedGraphicsTest { public class PicboxCus : System.Windows.Forms.PictureBox { Random random; Pen p = new Pen(new SolidBrush(Color.White)); Font font = new Font("黑体", 15); SolidBrush solidBrush = new SolidBrush(Color.Red); List<DateTime> lstTime = new List<DateTime>(); [Description("是否启用双缓冲绘制"), Category("自定义"), DefaultValue(false)] public bool isBufferDraw { get; set; } public PicboxCus() : base() { random = new Random(); } void BufferDraw(Graphics grap, Rectangle rect, int i, double fps) { using (BufferedGraphics bufferedGraphics = BufferedGraphicsManager.Current.Allocate(grap, rect))//创建缓冲 Graphics对象,区域 { bufferedGraphics.Graphics.Clear(Color.Black); for (int index = 0; index < i; index++) { int l = random.Next(rect.Width); int r = random.Next(rect.Height); int w = random.Next(100) + 1; int h = random.Next(100) + 1; bufferedGraphics.Graphics.DrawEllipse(p, new RectangleF(l, r, w, h)); } bufferedGraphics.Graphics.DrawString(fps.ToString("fps:#.#"), font, solidBrush, new Point(20, 20)); bufferedGraphics.Render(grap); } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); lstTime.Add(DateTime.Now); if (lstTime.Count > 1000) { lstTime.RemoveAt(0); } double fps = lstTime.Count / (lstTime.Last() - lstTime.First()).TotalSeconds; Rectangle rect = this.ClientRectangle; //获取tabcontrol背景区域 e.Graphics.SmoothingMode = SmoothingMode.HighQuality;//画图质量 e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; int i = 10000; if (isBufferDraw) { //启用缓冲绘制 BufferDraw(e.Graphics, rect, i, fps); } else { e.Graphics.Clear(Color.Black); for (int index = 0; index < i; index++) { int l = random.Next(rect.Width); int r = random.Next(rect.Height); int w = random.Next(100) + 1; int h = random.Next(100) + 1; e.Graphics.DrawEllipse(p, new RectangleF(l, r, w, h)); } e.Graphics.DrawString(fps.ToString("fps:#.#"), font, solidBrush, new Point(20, 20)); } Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff")); } } }
查看 BufferedGraphics.Render() 方法,内部是通过 BitBlt() 绘制的。