views:

189

answers:

3

Can we compare two Image objects with C#? For example, check whether they are equal, or even better check how similar are their pixels?

if possible, how?

+1  A: 

The simplest place to start would be dimensions. If the dimensions are not equal, you may be able to declare them false.

If you need to go through them pixel-by-pixel, you'll need two for loops. Something along these lines:

Bitmap ImageA...
Bitmap ImageB...

for ( Int64 x = 0; x < ImageA.Width; x++ )
{
     for ( Int64 y = 0; y < ImageA.Height; y++ )
     {
         if ( ImageA.GetPixel(x, y) != ImageB.GetPixel(x, y) )
         {
            return false;
         }
     }
}

It's pseudo-code (the functions exist in C#, although I can't recall them at the moment) and very simplistic, but is how you'd want to perform a basic pixel-to-pixel check.

Note, however, for that loop to work the images must be of the same dimensions. If they aren't, you're likely to get exceptions if you try to sample a pixel outside of the smaller one's area. It also won't be terribly fast to compare the pixels, so you may want to find another way of discarding possible duplicates first.

Edit: I'm not sure how to do this on an Image, but it is quite simple for Bitmaps. There isn't a visible way of getting Image pixel data out of the class. It appears the Bitmaps inherit from Images, though, so this may still work. Given that Images are an abstract class for both Bitmaps and Metafiles, they may not have a simple internal pixel list.

peachykeen
So, I will just mention that if the two images are relatively large, this will be slow as a dog. I would use Lockbits and also loop through by row instead of column as that is how it will be arranged in memory.
Ed Swangren
+1  A: 

You can use a set of tools called TestApi, which is an open-source library to aid unit testing. One of such API is called Visual Verification API, and it does exactly what you need - it can compare two images and tell you if they are equal:

// 1. Capture the actual pixels from a given window
Snapshot actual = Snapshot.FromRectangle(new Rectangle(0, 0, 100, 100));

// 2. Load the reference/master data from a previously saved file
Snapshot expected = Snapshot.FromFile("Expected.png"));

// 3. Compare the actual image with the master image
//    This operation creates a difference image. Any regions which are identical in 
//    the actual and master images appear as black. Areas with significant 
//    differences are shown in other colors.
Snapshot difference = actual.CompareTo(expected);

// 4. Configure the snapshot verifier - It expects a black image with zero tolerances
SnapshotVerifier v = new SnapshotColorVerifier(Color.Black, new ColorDifference());

// 5. Evaluate the difference image
if (v.Verify(difference) == VerificationResult.Fail)
{
    // Log failure, and save the diff file for investigation
    actual.ToFile("Actual.png", ImageFormat.Png);
    difference.ToFile("Difference.png", ImageFormat.Png);
}
hmemcpy