BufferedGraphics 性能测试

 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"));

        }




    }
}

MSDN 介绍: https://docs.microsoft.com/zh-cn/dotnet/framework/winforms/advanced/how-to-manually-render-buffered-graphics

查看 BufferedGraphics.Render() 方法,内部是通过 BitBlt() 绘制的。

原文地址:https://www.cnblogs.com/howtrace/p/11414079.html