双缓冲绘图,是指先在内存中进行各种绘图操作,在将内存中绘制好的图形取出显示在控件上,这样可以避免窗口闪烁的现象。
根据上述原理,我们可以自行实现双缓冲绘图,示例代码如下:
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);
}
}
但是该方法有个缺点,就是 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();
}