绘制图形性能问题

时间:2009-07-19 13:23:23

标签: c# .net performance graphics

我正在尝试创建滑块移动图形。代码解释得更好。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace temp
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private System.Drawing.Graphics g;
        private System.Drawing.Pen pen1 = new System.Drawing.Pen(Color.Black, 1F);

        //timer for animation
        private void Form1_Load(object sender, EventArgs e)
        {
            Timer a = new Timer();
            a.Interval = 60;
            a.Tick += new EventHandler(a_Tick);
            a.Start();
        }

        void a_Tick(object sender, EventArgs e)
        {
            button1_Click(this, null);

        }

        //draws randomly generated point array.
        int cnt = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            rAr();
            g = pictureBox1.CreateGraphics();

            g.Clear(Color.Violet);
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.DrawCurve(pen1, points2);
            cnt++;
        }

        Random r = new Random();
        Point[] p = new Point[100];
        Point[] points2 = new Point[100];
        int c = 4;
        //fills new random point array
        private void rAr()
        {
            points2.CopyTo(p, 0);
            int cc = 1;
            for (int i = points2.Length - 1; i > 0; i--)
            {
                points2[i - 1] = new Point(100 - cc, p[i].Y);
                cc++;
            }
            points2[99] = new Point(100, r.Next(1, 50));
        }

    }
}

这段代码工作正常,问题是它需要很多cpu和自动化不是很顺利。有没有其他方法来实现相同的东西,更少的CPU。 谢谢你的重播

2 个答案:

答案 0 :(得分:7)

(过早)优化

除了已发布的其他答案外,您还试图通过100个点绘制样条曲线。

这可能是个坏主意,原因有二:首先,在任何情况下,将曲线拟合到100点并不是特别快的事情。其次,由于这些点相距1个像素,因此使用曲线可能没有视觉上的好处。

因此,您可以采取更多措施来提高速度:

  • 尝试使用PolyLine而不是曲线

  • 如果您需要使用曲线,那么您可能不需要在绘图的100个像素上使用100个点 - 在该宽度上使用10或20个位置可以提供更好的结果,并且会显着减少.net必须做的曲线拟合工作。

  • 您也可以删除位于线条/曲线上的某些中间点,以便绘制更少的线条。例如如果你在(10,57)(11,57)(12,57)得分,那么你可以放下中间点并从(10,57)到(12,57)画一条直线。

错误的算法?

但是等等!在优化代码之前 - 它实际上是问题的正确解决方案吗?

听起来好像内容不是为了“改变”,而是简单地向侧面滚动。在这种情况下,只有在图像一侧引入的新像素实际上在每个帧中“改变” - 其余的只是侧向移动。在这种情况下,您可以滚动(移动)包含“旧”曲线图像的图形区域,然后只绘制“滚动到视图中”的额外像素。以这种方式滚动可以通过几种不同的方式实现(例如,在图形中进行blitting,或者如果整个窗口的内容是滚动,则使用windows Form滚动命令)

以同样的方式,如果数据没有改变,而只是“滚动”,那么为每一帧重建阵列是不必要的。使用循环缓冲区,您只需在数组的“结尾”添加一个新点,并从头开始删除一个,而无需重新分配数组或复制所有中间点。

所以关于使用正确的工具来完成工作。

答案 1 :(得分:3)

您应该将Button1中的所有图形代码移动到图片框的绘图事件中,如下所示:

   private void button1_Click(object sender, EventArgs e)
    {
        rAr();
        pictureBox1.Invalidate();
        cnt++;
    }

private void picturebox1_Paint(object sender PaintEventArgs e)
{
    using graphics g = e.Graphics()
    {
          g.Clear(Color.Violet);
          g.PixelOffsetMode = PixelOffsetMode.HighQuality;
          g.SmoothingMode = SmoothingMode.HighQuality;
          g.DrawCurve(pen1, points2);

    }
}