如何在C#中快速捕获位图数据

时间:2016-03-14 04:54:12

标签: c# performance bitmap system.drawing

我的目标是能够拍摄70个像素的行,分析所有70个像素以获得某种颜色,然后在满足条件时再投射到另一个函数。这需要每50毫秒至少发生一次,最好甚至比这更快。

我目前的代码是这样的

    public void CaptureArea()
    {
        using (Bitmap capture = new Bitmap(70, 35))
        {
            using (Graphics g = Graphics.FromImage(capture))
            {
                for (int i = 0; i < 10; i++)
                {
                    g.CopyFromScreen(copyPoint, pastePoint, new Size(70, 35));
                    evaluteBitmap(capture);
                }
            }
        }
    }
    public void evaluteBitmap(Bitmap scanArea)
    {
        Rectangle rect = new Rectangle(0, 0, 70, 35);
        BitmapData data = scanArea.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        IntPtr ptr = data.Scan0;

        int bytes = data.Stride * scanArea.Height;
        byte[] rgbValues = new byte[bytes];
        byte[] r = new byte[bytes / 3];
        byte[] g = new byte[bytes / 3];
        byte[] b = new byte[bytes / 3];

        Marshal.Copy(ptr, rgbValues, 0, bytes);

        int count = 0;
        int stride = data.Stride;

        for (int column = 0; column < 30; column++)
        {
            b[count] = (byte)(rgbValues[(column * stride) + (34 * 3)]);
            g[count] = (byte)(rgbValues[(column * stride) + (34 * 3) + 1]);
            r[count++] = (byte)(rgbValues[(column * stride) + (34 * 3) + 2]);
        }

        scanArea.UnlockBits(data);
    }

只需CaptureArea()每秒就可以将大约60个位图丢失到内存中,这很好,但是目前EvaluateBitmap()需要大约600毫秒来抓取像素并将其分成RGB值70次。

最终结果是,当需要更接近50毫秒时,单帧数据需要超过500毫秒才能进行处理。这种解决问题的方法超出了我的范围,而且我对这种性质的代码没有足够的经验,能够提供解决方案并知道最终会更快或更慢以及会有多少。

有没有办法让我的表现更快一个数量级,或者我问不可能?

1 个答案:

答案 0 :(得分:1)

给定代码的分析会话给出了明确的结果:

  

CopyFromScreen - 40.00%独家样品
  Bitmap..ctor - 15.00%独家样品
  clr.dll - 11.67%独家样本
  KernelBase.dll - 8.33%独家样本
  GdiPlus.dll - 6.67%独家样本
  LockBits - 6.67%独家样品
  Image.Dispose - 5.00%独家样品
    ....
    ....
  EvaluateBitmap - 1.67%独家样本
    ....
    ....
  CaptureArea - 0.0%独家样本

最大的时间花在.NET方法上,这些方法无法改进。

结论:代码没有可能的显着改进。 但是,您可以使用多线程在给定时间段内处理更多帧。