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

How can I capture bitmap data very quickly in C#

我的目标是能够获取一行 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 多毫秒来处理。这种问题的解决超出了我的范围,我对这种性质的代码没有足够的经验,无法眼球解决方案并知道最终会更快或更慢的速度以及速度。

有没有办法让我的性能提高一个数量级,或者我是在问不可能的事情?

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

CopyFromScreen - 40.00% exclusive samples
Bitmap..ctor - 15.00% exclusive samples
clr.dll - 11.67% exclusive samples
KernelBase.dll - 8.33% exclusive samples
GdiPlus.dll - 6.67% exclusive samples
LockBits - 6.67% exclusive samples
Image.Dispose - 5.00% exclusive samples
....
....
EvaluateBitmap - 1.67% exclusive samples
....
....
CaptureArea - 0.0% exclusive samples

大部分时间花在无法改进的 .NET 方法上。

结论:代码没有明显的改进。 不过,您或许可以使用多线程在给定时间段内处理更多帧。