4
public void winCheck()
{
    if (button1.Image == img1)
    {
        w1 = "P2";
        button1.Image = new Bitmap(@"win_cross.png");
        button2.Image = new Bitmap(@"win_cross.png");
        button3.Image = new Bitmap(@"win_cross.png");
    }
}

Here both button1.Image and img1 have same image but still, the control doesn't go into the if block. Is their any property of both such that value of both will be same.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
heartofrevel
  • 181
  • 1
  • 3
  • 12
  • Are you trying to say that the image are the same because they are bit per bit identical (they show the same image)? How do you initialize the button1.Image and the img1 variable? – Steve Feb 08 '14 at 15:28
  • Actually they are the same image bit per bit , i have intialized the button1.Image in button1 click event handler and i created img1(Image)(public) variable in the main class itself. – heartofrevel Feb 08 '14 at 15:30
  • possible duplicate of [Comparing Images](http://stackoverflow.com/questions/6412778/comparing-images) – Sebastian Negraszus Feb 08 '14 at 15:34
  • 2
    Thisn is very poor coding to rely on graphical element to hold states and test these states. You should instead define an enumeration for the various states, have a field typed with this enum, and define a method that refreshes your controls image depending on the field enum value. – Patrick from NDepend team Feb 08 '14 at 15:36
  • This is a nice example: http://www.dotnetexamples.com/2012/07/fast-bitmap-comparison-c.html – Idov Feb 08 '14 at 15:44

3 Answers3

9

Here is one possibility to do it, if you can have unsafe code and if you want images to be exactly the same on byte level:

public unsafe static bool AreEqual(Bitmap b1, Bitmap b2)
{
    if (b1.Size != b2.Size)
    {
        return false;
    }

    if (b1.PixelFormat != b2.PixelFormat)
    {
        return false;
    }

    if (b1.PixelFormat != PixelFormat.Format32bppArgb)
    {
        return false;
    }

    Rectangle rect = new Rectangle(0, 0, b1.Width, b1.Height);
    BitmapData data1
        = b1.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);
    BitmapData data2
        = b2.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);

    int* p1 = (int*)data1.Scan0;
    int* p2 = (int*)data2.Scan0;
    int byteCount = b1.Height * data1.Stride / 4; //only Format32bppArgb 

    bool result = true;
    for (int i = 0; i < byteCount; ++i)
    {
        if (*p1++ != *p2++)
        {
            result = false;
            break;
        }
    }

    b1.UnlockBits(data1);
    b2.UnlockBits(data2);

    return result;
}

This compares images "literally" - all bytes need to be exactly the same. Other possibility would be to compare colours of pixels - then PixelFormats wouldn't have to be the same (taken from here):

public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
{
    CompareResult cr = CompareResult.ciCompareOk;

    //Test to see if we have the same size of image
    if (bmp1.Size != bmp2.Size)
    {
        cr = CompareResult.ciSizeMismatch;
    }
    else
    {
        //Sizes are the same so start comparing pixels
        for (int x = 0; x < bmp1.Width 
             && cr == CompareResult.ciCompareOk; x++)
        {
            for (int y = 0; y < bmp1.Height 
                         && cr == CompareResult.ciCompareOk; y++)
            {
                if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
                    cr = CompareResult.ciPixelMismatch;
            }
        }
    }
    return cr;
}

This can be however very slow. The same link contains an interesting idea of comparing hash values:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Security.Cryptography;

namespace Imagio
{
    public class ComparingImages
    {
        public enum CompareResult
        {
            ciCompareOk,
            ciPixelMismatch,
            ciSizeMismatch
        };

        public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
        {
            CompareResult cr = CompareResult.ciCompareOk;

            //Test to see if we have the same size of image
            if (bmp1.Size != bmp2.Size)
            {
                cr = CompareResult.ciSizeMismatch;
            }
            else
            {
                //Convert each image to a byte array
                System.Drawing.ImageConverter ic = 
                       new System.Drawing.ImageConverter();
                byte[] btImage1 = new byte[1];
                btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());
                byte[] btImage2 = new byte[1];
                btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());

                //Compute a hash for each image
                SHA256Managed shaM = new SHA256Managed();
                byte[] hash1 = shaM.ComputeHash(btImage1);
                byte[] hash2 = shaM.ComputeHash(btImage2);

                //Compare the hash values
                for (int i = 0; i < hash1.Length && i < hash2.Length 
                                  && cr == CompareResult.ciCompareOk; i++)
                {
                    if (hash1[i] != hash2[i])
                        cr = CompareResult.ciPixelMismatch;
                }
            }
            return cr;
        }
    }
}
BartoszKP
  • 34,786
  • 15
  • 102
  • 130
0

Your code doesn't work because you are comparing the variables pointing to the images (i.e. in memory address) not the image data (pixels).

See ImageComparer.Compare method. Has overloads to specify tolerance. It is available since VS2012.

https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.uitesting.imagecomparer.compare.aspx

Havenard
  • 27,022
  • 5
  • 36
  • 62
user3285954
  • 4,499
  • 2
  • 27
  • 19
-7

dont use double equal (==). use equals method. (if button1.Image.equals(img1)) // you code

Asad Ali
  • 31
  • 5
  • 1
    -1: Bitmap does not implement "Equals". It compares references by default. – Idov Feb 08 '14 at 15:34
  • it's giving a NullReferenceException - Object reference not set to an instance of an object. – heartofrevel Feb 08 '14 at 15:35
  • then one of your image is null. check for it @k3rn3l – Asad Ali Feb 08 '14 at 15:48
  • 1
    @AsadAli Why don't you test it yourself? **Bitmap b1 = (Bitmap)Bitmap.FromFile(fname); Bitmap b2 = (Bitmap)Bitmap.FromFile(fname); var isEqual = b1.Equals(b2);** – L.B Feb 08 '14 at 17:33