什么是最快的GDI+渲染设置?

17

有很多关于呈现高质量图形的帖子,比如这篇:

高质量图像缩放库

我需要在使用GDI+绘制约6k个线条和椭圆的图形时,以大约10fps的帧率呈现。因此,我需要我的图形具有尽可能低的质量属性。

这是我所做的:

public static class GraphicsExtensions
{
    public static void ToHighQuality(this Graphics graphics)
    {
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
    }

    public static void ToLowQuality(this Graphics graphics)
    {
        graphics.InterpolationMode = InterpolationMode.Low;
        graphics.CompositingQuality = CompositingQuality.HighSpeed;
        graphics.SmoothingMode = SmoothingMode.HighSpeed;
        graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
        graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
    }
}

我有遗漏某些东西吗,还是这是图形属性的最佳极值?
使用较低模式绘制时,我每秒绘制5帧(202毫秒/帧),而使用较高模式时,我每秒绘制3帧(330毫秒/帧)。
我觉得差别不大,但我已经将性能问题减少到仅绘制...

一些数字:


4
为什么不使用DirectX或WPF? - Daniel A. White
3
在每一帧中,所有的2k个对象都在移动吗?否则请使用单独的叠加缓冲区来处理静态/动态对象。否则,请考虑使用Direct2D绘图。 - Anders Forsgren
建议(可能不是最好的):将线条、椭圆和文本组合成一个 GraphicsPath 对象。 - leppie
1
好的,如果我在gdi+中找不到更好的解决方案,我会记住你们所有的想法! - Cyril Gandon
通常情况下,NearestNeighbour 应该低于 low(除非它们是相同的)。http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.interpolationmode(v=vs.110).aspx 上没有太多的文档资料。 - Andreas Reiff
2个回答

18

GDI+并不是一个高性能的渲染解决方案。如果想获得更好的原始性能,请使用p/invoke到GDI或直接使用DirectX。然而,通过仅优化重绘可以很容易地实现2倍速度提升:

你真的需要这么多绘制吗?去掉一些元素后图像是否仍能正常工作?

你是否正在创建和销毁大量笔刷和画笔,或者正在重复使用几个预定义的笔刷和画笔?

在构建或转换形状时,是否有任何处理可以在预处理步骤中完成,以便在重绘过程中不必重复执行?

你是否在绘制任何不必要的内容?丢弃屏幕外的任何内容。如果存在大量超绘,则可能可以检测到并丢弃完全被前面物体遮挡的形状。

你是否可以将多条线路合并为单个折线?每个函数调用都会增加开销,因此,如果您可以使用单个函数调用绘制多个形状或线路,则速度会更快。

是否必须使用椭圆?如果它们很小,则可以尝试使用8或12边形代替椭圆,而不会明显降低形状的质量,这样可以获得更好的性能。

优化重复。如果形状是规则的(例如,您正在以相同颜色绘制大量10像素圆),那么可以将一个绘制到位图中,然后将副本传输。如果有规律的模式(例如棋盘格)则可以将其小片段绘制到位图上,并通过位块传输将其重复到整个图像中。(只需确保绘制位图时不进行缩放,并且它们与屏幕匹配(dpi和bpp),这样就可以获得最快的传输类型,而不会出现缓慢的双线性滤波模糊问题)

如果存在许多颜色更改,是否可以将它们批处理在一起,以便绘制所有红色物品,然后绘制所有蓝色物品等-这避免了频繁切换笔/画笔。

有时避免裁剪可能会对性能有所帮助 - 例如,如果您绘制文本并且知道所有文本都可见,可以禁用裁剪进行绘制。(这曾经提供了性能优势 - 尽管它可能在硬件加速渲染中没有帮助,但还是值得一试)
最后,请记住,在硬件加速的情况下,禁用某些渲染功能可能无法提高性能。如果显卡能够以每秒500帧的速度绘制10,000个椭圆形,但您只看到10帧每秒,则禁用抗锯齿可能不会提高帧率 - 瓶颈更可能是您的代码和GDI+花费了很长时间来告诉显卡要渲染什么而不是图形本身渲染缓慢。(您的情况可能有所不同 - 这将取决于您正在呈现什么,GDI+如何处理它,是否进行了硬件加速,图形驱动程序如何处理它以及您的显卡有多强大)。

1

要绘制图像,请转到低质量:

img = new Bitmap(img, w / 2, h / 2);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接