【问题标题】:Drawing.Graphics, poor performance绘图.图形,性能差
【发布时间】:2019-08-28 13:55:50
【问题描述】:

我目前正在开发一个 C# 应用程序,该应用程序使用 Drawing.Graphics 绘制到我在图片框中显示的位图。我正在渲染一个带有网格的图形,所以除了屏幕上的一些点之外,我还必须绘制大约 200 条网格线。我可以滚动以在图表中移动,但在这样做的同时,我注意到我的绘图功能表现不佳,因为它结结巴巴。用 OpenTK 和它的 GLControl 类替换这种方法使得渲染非常高效,滚动非常流畅。

有什么方法可以让 Drawing.Graphics 获得更快的性能?

  // This is only done when the window is resized
  Bitmap bmp = new Bitmap(picRender.Width, picRender.Height);
  Graphics g = Graphics.FromImage(bmp);

  // Drawing code
  g.Clear(picRender.BackColor);
  g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
  g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
  if (background != null)
  {
   g.DrawImage(background, new Rectangle(0, 0, picRender.Width, picRender.Height));
  }

  for (int n = 0; n < trajectories.Count; n++)
  {
   Trajectory trajectory = trajectories[n];

   Pen pen = new Pen(new SolidBrush(TrajectoryColors[n % TrajectoryColors.Length]));

   if (RenderLines)
   {
    for (int i = 0; i < trajectory.samples.Count - 1; i++)
    {
        if (Interval_Start > trajectory.samples[i + 1].time ||
         Interval_End < trajectory.samples[i].time) { continue; }

        g.DrawLine(pen, coordinate_system.ToPoint(trajectory.samples[i].coordinates),
         coordinate_system.ToPoint(trajectory.samples[i + 1].coordinates));
    }
   }
  }
  // End of drawing

【问题讨论】:

  • @Dmi,你能显示一些代码吗?性能可能取决于您采用的方法,因此拥有该类型上下文会有所帮助。
  • 从位图创建图形,DrawLine x200,处理图形。 :)
  • 我曾经为 Windows Phone 7 制作了 System.Drawing.Graphics 的硬件加速版本。虽然这不是最好的方法;除非你有充分的理由重写 GDI+。 OpenTK 的图形处理方法很快,因为它使用 GPU 加速。
  • @Dmi:向我们展示代码。它可能是 System.Graphics,也可能是您的代码。在我看到你的代码之前,我必须假设它是你的代码。
  • 您在抱怨滚动性能,此代码在滚动期间不运行。以 Format32bppPArgb 像素格式创建位图,它的渲染速度比其他任何格式都快 10 倍。

标签: .net graphics


【解决方案1】:

除了优化绘图代码之外,另一个可以使用的策略是缓冲结果。

每次都重绘整个图像,而只更新刚刚滚动到视图中的部分(或者更好的是:即将滚动到视图中)

如果您需要更多信息,我们需要查看一些代码来帮助您进行分析。

【讨论】:

    【解决方案2】:

    您可以通过将Graphics.SmoothingMode 属性设置为SmoothingMode.None 来关闭抗锯齿。

    【讨论】:

      【解决方案3】:

      OpenGL 和 System.Graphics (GDI+) 使用不同类型的“绘图”。

      OpenGL 使用显卡,因此重绘既快速又便宜。 WindowsForms 中的 System.Graphics 使用 GDI+,由 CPU 执行,因此与 GPU 相比速度非常慢。

      有许多技巧可以使用 GDI+ 加速渲染。 一种是将代码更改为仅重绘已更改/移动的部分。但保留其余部分。

      【讨论】:

        【解决方案4】:

        您为每个轨迹、每个帧创建一个新画笔和一个新笔:

        Pen pen = new Pen(new SolidBrush(TrajectoryColors[n % TrajectoryColors.Length]));
        

        Pen(肯定)和SolidBrush(最终)实现IDisposable——它们应该被明确地处理,并且如果可能的话,它们不应该存在于高性能渲染循环中。如果您需要动态着色,您也许可以缓存这些笔。

        如果不测量时间,我会怀疑这可能会改善您的渲染。 GDI 渲染通常非常快(与 WPF 矢量图形相反),200 行不算什么。抗锯齿性能可能取决于您的 GPU 驱动程序。它看起来好多了,您无法将其关闭。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-07
          • 2019-09-10
          • 1970-01-01
          • 2011-11-10
          • 1970-01-01
          • 2015-09-12
          • 2017-02-26
          相关资源
          最近更新 更多