是否应该在我已经从位图绘制的面板上进行双缓冲,以最大程度地减少闪烁?
Should Double Buffering be done on a panel where I'm already drawing from a Bitmap, to minimize flicker?
我理解对面板进行双缓冲基本上意味着所有绘图都完成到缓冲区,然后缓冲区直接复制到绘图表面。
我正在绘制位图,然后使用 Graphics.DrawImage
将该位图绘制到我的面板,这样我就可以保存位图并对其进行更新,而无需重新执行所有绘制操作。
就面板的闪烁而言,这是否与双缓冲面板相同?
或者,我是否应该双缓冲并重新绘制所有绘图,如果这意味着我会得到更低的闪烁?
编辑:
我正在用 DrawLine
绘制点,这些点是动态生成的,一旦完成绘制,我就不会存储点。如果我做双缓冲区,我还必须承担存储我绘制的所有点的内存开销。
双缓冲区的工作方式应该有点不同。比方说,当您修改缓冲区 A 时,它应该使用缓冲区 B 绘制;然后当你开始修改缓冲区 B 时,它应该从 A 读取。
所以,想法是不写入正在读取的缓冲区。因此,使用外部缓冲区并将其复制到绘图缓冲区似乎与双缓冲区不同。实际上,可以通过在读取缓冲区时复制外部缓冲区来写入缓冲区。
最佳解决方案将主要取决于您绘制的内容、操作次数、涉及的像素数以及绘图表面的总大小。
一个常见的例子是绘图程序,用户在其中将笔画堆叠在笔画上,每个笔画由数百个点组成..
一般来说,建议让系统负责对您绘制的控件进行双缓冲。它会做得比你希望的更好..
因此您应该在 Paint
事件中重新绘制,而不是尝试实现您自己的缓冲位图绘制以消除闪烁。
闪烁会消失,但是如果有大量绘图操作,这会很慢并导致延迟。
为避免延迟,您可以结合两种方法的优点:
绘制 图形直到它们太多;这取决于绘图调用(主要是涉及的像素数)和系统速度,您是否可以在注意到滞后之前承受数百或数万次绘图调用,比如在 N
调用之后。
然后 缓存 第一个 N
绘图调用,方法是绘制成一个位图,然后将其设置为 Panel's BackgroundImage
。 N+1
中的所有绘图仍将在 Paint
事件中绘制到面板的表面上。当您到达 2*N
时,您会创建另一个版本的缓存图像,在 2*N+1
开始绘制表面,依此类推..
我理解对面板进行双缓冲基本上意味着所有绘图都完成到缓冲区,然后缓冲区直接复制到绘图表面。
我正在绘制位图,然后使用 Graphics.DrawImage
将该位图绘制到我的面板,这样我就可以保存位图并对其进行更新,而无需重新执行所有绘制操作。
就面板的闪烁而言,这是否与双缓冲面板相同?
或者,我是否应该双缓冲并重新绘制所有绘图,如果这意味着我会得到更低的闪烁?
编辑:
我正在用 DrawLine
绘制点,这些点是动态生成的,一旦完成绘制,我就不会存储点。如果我做双缓冲区,我还必须承担存储我绘制的所有点的内存开销。
双缓冲区的工作方式应该有点不同。比方说,当您修改缓冲区 A 时,它应该使用缓冲区 B 绘制;然后当你开始修改缓冲区 B 时,它应该从 A 读取。
所以,想法是不写入正在读取的缓冲区。因此,使用外部缓冲区并将其复制到绘图缓冲区似乎与双缓冲区不同。实际上,可以通过在读取缓冲区时复制外部缓冲区来写入缓冲区。
最佳解决方案将主要取决于您绘制的内容、操作次数、涉及的像素数以及绘图表面的总大小。
一个常见的例子是绘图程序,用户在其中将笔画堆叠在笔画上,每个笔画由数百个点组成..
一般来说,建议让系统负责对您绘制的控件进行双缓冲。它会做得比你希望的更好..
因此您应该在 Paint
事件中重新绘制,而不是尝试实现您自己的缓冲位图绘制以消除闪烁。
闪烁会消失,但是如果有大量绘图操作,这会很慢并导致延迟。
为避免延迟,您可以结合两种方法的优点:
绘制 图形直到它们太多;这取决于绘图调用(主要是涉及的像素数)和系统速度,您是否可以在注意到滞后之前承受数百或数万次绘图调用,比如在
N
调用之后。然后 缓存 第一个
N
绘图调用,方法是绘制成一个位图,然后将其设置为Panel's BackgroundImage
。N+1
中的所有绘图仍将在Paint
事件中绘制到面板的表面上。当您到达2*N
时,您会创建另一个版本的缓存图像,在2*N+1
开始绘制表面,依此类推..