双缓冲原理以及双缓冲原理的实例

何谓“双缓冲”?它的基本原理就是:

先在内存中开辟一块虚拟画布,然后将所有需要画的图形先画在这块“虚拟画布”上,最后在一次性将整块画布画到真正的窗体上。

因为所有的单个图形的绘制都不是真正的调用显示系统来“画”,所以不会占用显示系统的开销,极大的提高的绘图效率。

实例1:

 1         #region 正常绘图
 2         /// <summary>
 3         /// 正常绘图
 4         /// </summary>
 5         private void NormalDraw()
 6         {
 7             DateTime t1 = DateTime.Now;
 8             Graphics g = this.CreateGraphics();
 9             Brush brush = null;
10 
11             bool flag = true;
12             if (flag)
13             {
14                 brush = new LinearGradientBrush(new PointF(0.0f, 0.0f), new PointF(700.0f, 300.0f), Color.Red, Color.Blue);
15                 flag = false;
16             }
17             else
18             {
19                 brush = new LinearGradientBrush(new PointF(0.0f, 0.0f),new PointF(700.0f, 300.0f), Color.Blue, Color.Red);
20                 flag = true;
21             }
22             for (int j = 0; j < 60; j++)
23             {
24                 for (int i = 0; i < 60; i++)
25                 {
26                     g.FillEllipse(brush, i * 10, j * 10, 10, 10);
27                 }
28             }
29             DateTime t2 = DateTime.Now;
30             TimeSpan sp = t2 - t1;
31             float per = 1000 / (sp.Milliseconds == 0 ? 1 : sp.Milliseconds);
32             this.label1.Text = "速度:" + per.ToString() + "帧/秒";
33         }
34         #endregion

实例2:

 1         #region 启用双缓冲的绘图
 2         /// <summary>
 3         /// 启用双缓冲的绘图
 4         /// </summary>
 5         private void EnableDoubleBuffer()
 6         {
 7             DateTime t1 = DateTime.Now;
 8 
 9             Bitmap bmp = new Bitmap(6000, 6000);    //在内存中建立一块画布
10             Graphics g = Graphics.FromImage(bmp);   //获取这块内存画布的Graphics引用:
11             Brush brush = null;
12 
13             bool flag = true;
14             if (flag)
15             {
16                 brush = new LinearGradientBrush(new PointF(0.0f, 0.0f), new PointF(700.0f, 300.0f), Color.Red, Color.Blue);
17                 flag = false;
18             }
19             else
20             {
21                 brush = new LinearGradientBrush(new PointF(0.0f, 0.0f),new PointF(700.0f, 300.0f), Color.Blue, Color.Red);
22                 flag = true;
23             }
24             for (int j = 0; j < 600; j++)
25             {
26                 for (int i = 0; i < 600; i++)
27                 {
28                     //在这块内存画布上绘图
29                     g.FillEllipse(brush, i * 10, j * 10, 10, 10);
30                 }
31             }
32 
33             //将内存画布画到窗口中
34             this.CreateGraphics().DrawImage(bmp, 0, 0);
35 
36             DateTime t2 = DateTime.Now;
37             TimeSpan sp = t2 - t1;
38             float per = 1000 / (sp.Milliseconds == 0 ? 1 : sp.Milliseconds);
39             this.label1.Text = "速度:" + per.ToString() + "帧/秒";
40         }
41         #endregion

以上虽然可以模拟双缓冲原理,但是会出现画图的时候内存占用过高,优化方案如下:

 1         /// <summary>
 2         /// 优化双缓冲绘图
 3         /// 内存占用很小
 4         /// </summary>
 5         private void DoubleBufferDrawOptimize()
 6         {
 7             DateTime t1 = DateTime.Now;
 8 
 9             //在内存中建立一块画布,使用using 语法及时释放资源,避免画图对象没有及时回收导致内存飙升
10             using (Bitmap bmp = new Bitmap(6000, 6000))
11             {
12                 //获取这块内存画布的Graphics引用,对画布也要及时回收资源,
13                 using (Graphics g = Graphics.FromImage(bmp))
14                 {
15                     Brush brush = null;
16 
17                     bool flag = true;
18                     if (flag)
19                     {
20                         brush = new LinearGradientBrush(new PointF(0.0f, 0.0f), new PointF(700.0f, 300.0f), Color.Red, Color.Blue);
21                         flag = false;
22                     }
23                     else
24                     {
25                         brush = new LinearGradientBrush(new PointF(0.0f, 0.0f), new PointF(700.0f, 300.0f), Color.Blue, Color.Red);
26                         flag = true;
27                     }
28                     for (int j = 0; j < 600; j++)
29                     {
30                         for (int i = 0; i < 600; i++)
31                         {
32                             //在这块内存画布上绘图
33                             g.FillEllipse(brush, i * 10, j * 10, 10, 10);
34                         }
35                     }
36                     //将内存画布画到窗口中
37                     this.CreateGraphics().DrawImage(bmp, 0, 0);
38                 }
39             }
40 
41             DateTime t2 = DateTime.Now;
42             TimeSpan sp = t2 - t1;
43             float per = 1000 / (sp.Milliseconds == 0 ? 1 : sp.Milliseconds);
44             this.label1.Text = "速度:" + per.ToString() + "帧/秒";
45         }

 

此代码是从别的技术群下载的群文件看到的,具有借鉴意义。

实例代码:https://files.cnblogs.com/files/wgx0428/Winfrom%E5%8F%8C%E7%BC%93%E5%86%B2%E7%BB%98%E5%9B%BE.zip

posted @ 2017-03-24 16:18  江宁织造  阅读(715)  评论(0编辑  收藏  举报