C#双缓冲技术实例详解

2019-12-26 18:07:18于丽


BufferedGraphicsContext current = BufferedGraphicsManager.Current; //(1)
BufferedGraphics bg;
bg = current.Allocate(this.CreateGraphics(),this.DisplayRectangle); //(2)
Graphics g = bg.Graphics;//(3)
//随机 宽400 高400
System.Random rnd = new Random();
int x,y,w,h,r,i;
for (i = 0; i < 10000; i++)
{
    x = rnd.Next(400);
    y = rnd.Next(400);
    r = rnd.Next(20);
    w = rnd.Next(10);
    h = rnd.Next(10);
    g.DrawEllipse(Pens.Blue, x, y, w, h);
}
bg.Render();//(4)
//bg.Render(this.CreateGraphics());
bg.Dispose();//(5)

3、自己开辟一个缓冲区(如一个不显示的Bitmap对象),在其中绘制完成后,再一次性显示。

完整代码如下:


Bitmap bt = new Bitmap(400, 400);
Graphics bg = Graphics.FromImage(bt);
System.Random rnd = new Random();
int x, y, w, h, r, i;
for (i = 0; i < 10000; i++)
{
    x = rnd.Next(400);
    y = rnd.Next(400);
    r = rnd.Next(20);
    w = rnd.Next(10);
    h = rnd.Next(10);
    bg.DrawEllipse(Pens.Blue, x, y, w, h);
}
this.CreateGraphics().DrawImage(bt, new Point(0, 0)); 

另外一个例子,差不多

Graphics对象的创建方式:

a、在内存上创建一块和显示控件相同大小的画布,在这块画布上创建Graphics对象。

接着所有的图元都在这块画布上绘制,绘制完成以后再使用该画布覆盖显示控件的背景,从而达到“显示一次仅刷新一次”的效果!

实现代码(在OnPaint方法中):


Rectangle rect = e.ClipRectangle;
Bitmap bufferimage = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(bufferimage);
g.Clear(this.BackColor);
g.SmoothingMode = SmoothingMode.HighQuality; //高质量
g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
foreach (IShape drawobject in doc.drawObjectList)
{
    if (rect.IntersectsWith(drawobject.Rect))
    {
      drawobject.Draw(g);
      if (drawobject.TrackerState == config.Module.Core.TrackerState.Selected
        && this.CurrentOperator == Enum.Operator.Transfrom)//仅当编辑节点操作时显示图元热点
      {
        drawobject.DrawTracker(g);
      }
    }
}
using (Graphics tg = e.Graphics)
{
    tg.DrawImage(bufferimage, 0, 0);//把画布贴到画面上
}

b、直接在内存上创建Graphics对象:


Rectangle rect = e.ClipRectangle;
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle);
Graphics g = myBuffer.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.Clear(this.BackColor);
foreach (IShape drawobject in doc.drawObjectList)
{
    if (rect.IntersectsWith(drawobject.Rect))
    {
      drawobject.Draw(g);
      if (drawobject.TrackerState == config.Module.Core.TrackerState.Selected
        && this.CurrentOperator == Enum.Operator.Transfrom)//仅当编辑节点操作时显示图元热点
      {
        drawobject.DrawTracker(g);
      }
    }
}
myBuffer.Render(e.Graphics);
g.Dispose();
myBuffer.Dispose();//释放资源