双缓冲绘图,是指先在内存中进行各种绘图操作,在将内存中绘制好的图形取出显示在控件上,这样可以避免窗口闪烁的现象。
根据上述原理,我们可以自行实现双缓冲绘图,示例代码如下:
private void Paint() { // tempImage -> 临时位图 // tempGraphics -> 临时位图的绘图对象 // viewGraphics -> 显示控件的绘图对象 using (Bitmap tempImage = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height)) using (Graphics tempGraphics = Graphics.FromImage(tempImage)) using (Graphics viewGraphics = pictureBox1.CreateGraphics()) { // 步骤一:在临时位图上绘图 tempGraphics.Clear(Color.Black); // 使用黑色填充 if (MainImage != null) tempGraphics.DrawImage(MainImage, 0, 0, pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); // 绘制图像 // 步骤二:将位图取出,绘制到显示控件上 viewGraphics.DrawImage(tempImage, 0, 0); } }
注:其中的
MainImage
是位图对象,自行实现即可。
但是该方法有个缺点,就是 Graphics.DrawImage()
这个函数的执行效率比较差,在绘制一些分辨率较大的图像时会显得力不从心,这对于在毫秒必争的图像处理领域显然无法接受。
所以就有了另外的双缓冲绘图的实现方法,就是将所有绘图操作都放到显示控件的 Paint
事件中去执行,然后我们仅需要执行 Control.Invalidate()
即可刷新显示控件。也就是说,我们将耗时操作都放在另外的线程中执行了,我们的绘图操作便不再占用时间了。示例代码如下:
private void pictureBox1_Paint(object sender, PaintEventArgs e) { // 这些事为了提高 Graphics 的执行效率 e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; // 绘图 if (MainImage != null) e.Graphics.DrawImage(MainImage, 0, 0, pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); } private void Paint() { pictureBox1.Invalidate(); }
注:
Form
控件的DoubleBuffered
属性要设置位True