首页 > 解决方案 > 为什么在比较位图时,LockBits 比比较像素快得多

问题描述

我有一个ImageCompare包含 2 个方法(CompareBitmapsFastCompareBitmapsSlow)的类,每个方法将 2 个位图作为参数,并使用慢速算法和快速算法比较它们。尽管具有更高的 for 循环迭代计数器,但 LockBits 的速度要快得多。为什么会这样?

public static class ImageCompare {
    public static bool CompareBitmapsFast(Bitmap bmp1, Bitmap bmp2)
    {
        if (bmp1 == null || bmp2 == null)
            return false;
        if (object.Equals(bmp1, bmp2))
            return true;
        if (!bmp1.Size.Equals(bmp2.Size) || !bmp1.PixelFormat.Equals(bmp2.PixelFormat))
            return false;

        int bytes = bmp1.Width * bmp1.Height * (Image.GetPixelFormatSize(bmp1.PixelFormat) / 8);

        bool result = true;
        byte[] b1bytes = new byte[bytes];
        byte[] b2bytes = new byte[bytes];

        BitmapData bitmapData1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, bmp1.PixelFormat);
        BitmapData bitmapData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, bmp2.PixelFormat);

        Marshal.Copy(bitmapData1.Scan0, b1bytes, 0, bytes);
        Marshal.Copy(bitmapData2.Scan0, b2bytes, 0, bytes);
        int fastCounter = 0;
        for (int n = 0; n <= bytes - 1; n++) {
            fastCounter++;
            if (b1bytes[n] != b2bytes[n])
            {
                result = false;
                break;
            }
        }

        bmp1.UnlockBits(bitmapData1);
        bmp2.UnlockBits(bitmapData2);
        Console.WriteLine("Number of for iterations in fast compare: " + fastCounter);
        return result;
    }
    public static bool CompareBitmapsSlow(Bitmap bmp1, Bitmap bmp2)
    {
        if (bmp1 == null || bmp2 == null)
            return false;
        if (object.Equals(bmp1, bmp2))
            return true;
        if (!bmp1.Size.Equals(bmp2.Size) || !bmp1.PixelFormat.Equals(bmp2.PixelFormat))
            return false;

        //Compare bitmaps using GetPixel method
        int slowCounter = 0;
        for (int column = 0; column < bmp1.Width; column++)
        {
            for (int row = 0; row < bmp1.Height; row++) {
                slowCounter++;
                if (!bmp1.GetPixel(column, row).Equals(bmp2.GetPixel(column, row)))
                    return false;
            }
        }

        Console.WriteLine("Number of for iterations in slow compare: " + slowCounter);
        return true;
    }
}
class Program {
    static void Main(string[] args) {
       var bmp1 = ScreenUtil.Capture(1000, 725, 1825, 800);
       var bmp2 = ScreenUtil.Capture(1000, 725, 1825, 800);

       Stopwatch sw = new Stopwatch();
       sw.Start();
       bool res1 = ImageCompare.CompareBitmapsSlow(bmp1, bmp2);
       sw.Stop();
       Console.WriteLine("CompareBitmapsSlow Time: {0} ms", sw.ElapsedMilliseconds);

       sw.Restart();
       bool res2 = ImageCompare.CompareBitmapsFast(bmp1, bmp2);
       sw.Stop();
       Console.WriteLine("CompareBitmapsFast Time: {0} ms", sw.ElapsedMilliseconds);
    }
}

主程序创建 2 个相同区域的屏幕截图,并使用它来比较两张图片。

标签: c#

解决方案


推荐阅读