C# Fast Bitmap Compare
This example controls that two bitmap object are same or not. In first method, we use the GetPixel method in Bitmap class. In second example, we use the memory comparison using BitmapData class. “Frog 1” and “Frog 2” files has 1024×768 pixel size. Their thumbnails are shown below. As result:
Total time in first example(Lazy Comparison): ~1644 ms
Total time in second example(Fast Comprasion): ~10 ms
Usage:
Bitmap bmp1 = (Bitmap)Bitmap.FromFile(@"C:\test\Frog 1.bmp"); Bitmap bmp2 = (Bitmap)Bitmap.FromFile(@"C:\test\Frog 2.bmp"); Stopwatch sw = new Stopwatch(); sw.Start(); bool res1 = BitmapComprasion.CompareBitmapsLazy(bmp1, bmp2); sw.Stop(); Console.WriteLine(string.Format("CompareBitmapsLazy Time: {0} ms", sw.ElapsedMilliseconds)); sw.Restart(); bool res2 = BitmapComprasion.CompareBitmapsFast(bmp1, bmp2); sw.Stop(); Console.WriteLine(string.Format("CompareBitmapsFast Time: {0} ms", sw.ElapsedMilliseconds)); //Output: //CompareBitmapsLazy Time: 1644 ms //CompareBitmapsFast Time: 10 ms
Frog 1 Thumbnail | Frog 2 Thumbnail |
![]() |
![]() |
Fast Bitmap Comparison Example:
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); for (int n = 0; n <= bytes - 1; n++) { if (b1bytes[n] != b2bytes[n]) { result = false; break; } } bmp1.UnlockBits(bitmapData1); bmp2.UnlockBits(bitmapData2); return result; }
Classic Bitmap Comparison Example:
public static bool CompareBitmapsLazy(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 for (int column = 0; column < bmp1.Width; column++) { for (int row = 0; row < bmp1.Height; row++) { if (!bmp1.GetPixel(column, row).Equals(bmp2.GetPixel(column, row))) return false; } } return true; }
… better yet, use memcmp from mscrt.dll library on each scan row.
Fast Bitmap Comparison Example.
It is very good.
Now I can compare image property)
On the two LockBits lines, any reason why you’re subtracting 1 from width and height? If you try to compare bitmaps of 1 width or height, you’ll get a Parameter Not Valid exception. Also, it seems likely that bitmaps that differ only in the rightmost column or bottom row would erroneously pass.
Thanks for comment. Fixed bug in code.
Very nice post! I can compare two images very fast.
Does the algorithm take into account the rotation of the bitmap?
Suppose we have two identical shapes but one rotated 45 ° with respect to the other, what will the result be?
Thanks a lot!
No, this algorithm compares bytes. You should implement bitmap similarity algorithm.
I get an error like this 🙁
https://i.hizliresim.com/gPXj3b.jpg
You should create BitmapComparison class and copy/paste methods(CompareBitmapsFast and CompareBitmapsLazy) into the class.
How to get output image when compare two images.If images are same will get output same image else get difference of those images in picturebox.
You can subtract the color values. If they are same, all values will be zero.
your post is helpful. Thanks
Thanx, helpfull post! its work with VB.
Hi Turgay, thank you, helped me !
You can speed up further by replacing the slow “for” loop by
Tested with .Net5.