【问题标题】:What are the fastest GDI+ rendering settings?最快的 GDI+ 渲染设置是什么?
【发布时间】:2012-01-09 18:22:12
【问题描述】:

有很多关于渲染高质量图形的帖子,比如这个

High Quality Image Scaling Library

我需要使用 GDI+ 以大约 10fps 的帧速率在图形中渲染大约 6k+ 对象(直线和椭圆)。所以我的图形需要尽可能低质量的属性。

这是我所做的:

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;
    }
}

我是否忘记了什么,或者这是 Graphics 属性的最佳极值?
我在较低模式下以 5fps(202 毫秒/图像)进行绘图,在较高模式下以 3fps(330 毫秒/图像)进行绘图。
我不觉得有很大的不同,但我已经将我的性能问题减少到仅绘图......

一些数字:

【问题讨论】:

  • 为什么不用directx或wpf?
  • 所有 2k 对象真的每帧都在移动吗?否则,对静态/移动对象使用单独的覆盖缓冲区。否则,请查看 Direct2D 绘图。
  • 建议(可能不会更好):将线条、省略号和文本组合成GraphicsPath 对象。
  • 好吧,如果我没有找到更好的 gdi+ 解决方案,我会记住你所有的想法!
  • 一般情况下,NearestNeighbour 应该低于 low(除非它们相同)。 msdn.microsoft.com/en-us/library/… 的文档不多。

标签: c# .net graphics rendering gdi+


【解决方案1】:

GDI+ 不是高性能渲染解决方案。 p/invoke 到 GDI 或直接使用 DirectX 如果您想要更好的原始性能。但是,通过稍微优化重绘通常可以实现 2 倍的加速:

你真的需要画那么多吗?删除某些元素后,图像仍然可以正常工作吗?

您是在创建和销毁大量钢笔和画笔,还是在重复使用一些预定义的? 您是否正在执行任何处理来构建或转换可以在预处理步骤中执行的形状,以便在重绘期间不会不必要地重复?

你是不是画了一些不必要的东西?剔除(丢弃)屏幕外的任何内容。如果发生大量过度绘制(很可能有 6000 个对象),则可以检测并丢弃完全被前面的事物遮挡的形状。

您可以将多条线组合成一条折线吗?每个函数调用都会增加开销,所以如果你可以用一个函数调用绘制多个形状或线条,它会运行得更快。

你必须使用省略号吗?如果它们很小,您可以使用 8 或 12 面多边形获得更好的性能,而不会显着降低形状质量 - 值得一试。

优化重复。如果形状是规则的(例如,您正在绘制许多相同颜色的 10 像素圆圈),则将一个绘制到位图,然后对副本进行 blit。如果有规则的图案(例如棋盘格),则将其中的一小部分绘制到位图上,然后对该部分进行 blit 以在您的图像中重复它。 (只需确保绘制未缩放的位图并且它们与屏幕(dpi 和 bpp)匹配,这样您就可以获得最快的 blit 类型,并且不会以缓慢的双线性过滤模糊混乱而告终)

如果有很多颜色变化,您是否可以将它们批处理在一起,以便绘制所有红色的东西,然后绘制所有蓝色的东西等等 - 这样可以避免在钢笔/画笔之间切换很多。

有时您可以通过避免剪辑来获得收益 - 例如如果您正在绘制文本并且您知道它们都是可见的,您可以在禁用剪切的情况下进行绘制。 (这用于提供性能优势 - 它可能对硬件加速渲染没有帮助,但值得一试)

最后,请记住,使用硬件加速,您可能无法通过禁用某些渲染功能获得收益。如果显卡能够以每秒 500 帧的速度绘制 10,000 个椭圆,但您只能看到 10 fps,那么禁用抗锯齿可能对您的帧速率没有帮助 - 瓶颈更有可能是您的代码和 GDI+ 需要很长时间告诉显卡要渲染什么,而不是图形渲染本身很慢。 (YMMV - 这将取决于您要渲染的内容、GDI+ 如何处理它、是否是硬件加速、图形驱动程序如何处理它以及您的显卡有多强大)

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 2014-02-25
      • 2016-07-29
      • 2012-10-20
      相关资源
      最近更新 更多