Search This Blog

Sunday, April 04, 2010

Comparing Two Images in C#

Comparing Two Images in C#

I’ve recently been doing a bit of work generating images, I have also need to compare the images that I generate with an image that has already exists.
I found a number of web sites that suggested the following way of comparing two images, by cycling through each pixel in an image and returning false if there is a mismatch in the pixels.


private bool ImageCompareArray(Bitmap firstImage, Bitmap secondImage)
{
bool flag = true;
string firstPixel;
string secondPixel;

if (firstImage.Width == secondImage.Width
&& firstImage.Height == secondImage.Height)
{
for (int i = 0; i < firstImage.Width; i++)
{
for (int j = 0; j < firstImage.Height; j++)
{
firstPixel = firstImage.GetPixel(i, j).ToString();
secondPixel = secondImage.GetPixel(i, j).ToString();
if (firstPixel != secondPixel)
{
flag = false;
break;
}
}
}
if (flag == false)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}



This seems as good a way as any to compare two images, however there are a lot of method calls within this method that could slow down the process of image comparison and when comparing a couple of thousand images this may set my computer chugging away.
Another way I have found of comparing two images is saving the image to a memory stream and then converting this stream to a base 64 string as below:

1: public static bool ImageCompareString(Bitmap firstImage, Bitmap secondImage)
2: {
3: MemoryStream ms = new MemoryStream();
4: firstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
5: String firstBitmap = Convert.ToBase64String(ms.ToArray());
6: ms.Position = 0;
7:
8: secondImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
9: String secondBitmap = Convert.ToBase64String(ms.ToArray());
10:
11: if (firstBitmap.Equals(secondBitmap))
12: {
13: return true;
14: }
15: else
16: {
17: return false;
18: }
19: }



I have tested the base 64 string / image comparison with a large number of images and changed just a single pixel and got the correct results. So far I have not tested the method with any images over 500 * 600. So, am unsure how it will deal with oversize images at the moment I will be dealing with images in the range of 256 * 256 so this will work fine for me.


Passing the following images, into the method will return true as both images are identical (except for the file name).




In contrast the below images are obviously different and will return a false from the method.






After running both of the method multiple times, the average speed of the image comparison using the base 64 string comparison was on average 0.1 second however, using the array method the image comparison took significantly longer on average 1.8 seconds if the images were identical and only 0.05 seconds if the images were different. For now I will be keeping with the string comparison.
Please leave a comment if you have improvements / alternative ways of comparing images.

Happy Programming

No comments:

Post a Comment

Leave your suggession & comment...