我有一个类ImageCompare
和2种方法(CompareBitmapsFast
和CompareBitmapsSlow
),每种方法都将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个相同区域的屏幕截图,并使用它们来比较两张图片。