Drawing.Graphics,表现不佳

时间:2011-04-17 16:33:37

标签: .net graphics

我目前正在开发一个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

4 个答案:

答案 0 :(得分:0)

在优化绘图代码之后,可以使用的另一种策略是缓冲结果。

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

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

答案 1 :(得分:0)

您可以将Graphics.SmoothingMode属性设置为SmoothingMode.None来关闭消除锯齿功能。

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

为每个轨迹,每个帧创建一个新的画笔和一支笔:

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

Pen(肯定)和SolidBrush(最终)实现IDisposable-应该对其进行显式处理,并且,如果可能的话,它们不应存在于高性能渲染循环中。如果需要动态着色,则可以缓存笔。

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