【问题标题】:Screenshot capture is extremely slow屏幕截图非常慢
【发布时间】:2012-12-05 05:35:02
【问题描述】:

我正在编写一个可以截取屏幕截图的应用程序,它需要超快(几秒钟)然后处理它们。这是我用来执行此操作的代码 - 它可以工作,但速度极慢。

using System.Drawing;
using System.Drawing.Imaging;

public static Bitmap CaptureScreen()
{
    Bitmap BMP = new Bitmap(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
                            System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,
                            System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    System.Drawing.Graphics GFX = System.Drawing.Graphics.FromImage(BMP);
    GFX.CopyFromScreen(System.Windows.Forms.Screen.PrimaryScreen.Bounds.X,
                        System.Windows.Forms.Screen.PrimaryScreen.Bounds.Y,
                        0, 0,
                        System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size,
                        System.Drawing.CopyPixelOperation.SourceCopy);

    return BMP;
}

用法 - :

Bitmap im1 = new Bitmap(CaptureScreen());

上面的代码运行良好,但至少需要 5 秒才能处理完。所以有人可以提供一种像上面那样的方法,除了更快,我也想使用前景窗口来捕获,而不是整个屏幕。

编辑这是比较代码!

private void timer2_Tick(object sender, EventArgs e)
{

    pictureBox1.Image = CaptureScreen();
    pictureBox2.Image = CaptureScreenOld();
    Bitmap im1 = (Bitmap)pictureBox1.Image;
    Bitmap im2 = (Bitmap)pictureBox2.Image;
    for (int y = 0; y < pictureBox1.Height; y++)
    {
        for (int x = 0; x < pictureBox1.Width; x++)
        {
            // Get the color of the current pixel in each bitmap
            Color color1 = im1.GetPixel(x, y);
            Color color2 = im2.GetPixel(x, y);

            // Check if they're the same
            if (color1 != color2)
            {
                // If not, generate a color...
                Color myRed = Color.FromArgb(90, 0, 0);
                // .. and set the pixel in one of the bitmaps
                im2.SetPixel(x, y, myRed);
                pictureBox2.Image = im2;
            }
        }
    }
}

【问题讨论】:

  • 您需要对图像做什么?为什么要将整个图像重新复制到另一个BitmapBitmap im1 = CaptureScreen(); 应该会节省很多时间。还有 5 秒?我在屏幕截图上运行框模糊需要更少的时间......这个屏幕有多大?
  • 相同的代码在我的系统(1680 x 1050 分辨率)上运行大约 120 毫秒。
  • 1600x900。它将第一个屏幕截图与第二个屏幕截图进行比较,第二个屏幕截图上与第一个屏幕截图不同的任何差异都用红色标记。我有这个工作。
  • @user1911675:那么,您的比较代码可能需要花费时间;请出示一下这段代码好吗?

标签: c# bitmap screen-capture


【解决方案1】:

好的,使用GetPixel 多次比较像素真的很慢。而是将您的位锁定到一个数组中:

private static void CompareBitmaps(Bitmap a, Bitmap b) {
    Stopwatch sw = new Stopwatch();

    sw.Start();

    var lockRect = new Rectangle(0, 0, a.Width, a.Height);
    BitmapData ad = a.LockBits(lockRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    BitmapData bd = b.LockBits(lockRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

    Int32[] apixels = new Int32[ad.Width * ad.Height];
    Int32[] bpixels = new Int32[bd.Width * bd.Height];

    Marshal.Copy(ad.Scan0, apixels, 0, apixels.Length);
    Marshal.Copy(bd.Scan0, bpixels, 0, bpixels.Length);

    for(int i = 0; i < apixels.Length; i++) {
        if(apixels[i] != bpixels[i]) {
            unchecked {
                bpixels[i] = (int)0xff5a0000;
            }
        }
    }

    Marshal.Copy(bpixels, 0, bd.Scan0, bpixels.Length);

    a.UnlockBits(ad);
    b.UnlockBits(bd);

    sw.Stop();

    Console.WriteLine("CompareBitmaps took {0}.", sw.Elapsed);
}

为此,我得到大约 240 毫秒的时间;够了吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多