0

I'm trying to write a method to test if pixel by pixel two images are equal, and a lot of the ways I'm seeing are really complicated and above my knowledge. This is the way I'm trying to do it, but I'm getting errors:

public boolean equals(Object other)
{
    if(!(other instanceof MyArt))
    {
        return false;
    }
    MyArt otherArtObject = (MyArt)other;
    for(int x = 0; x < image.getWidth(); x++)
    {
        for(int y = 0; y < image.getHeight(); y++)
        {
            Pixel pixelObj = this.image.getPixel(x,y);
            Pixel otherPixelObj = otherArtObject.image.getPixel(x,y);
            if((pixelObj == otherPixelObj)&&(pixelObj.getRed()==otherPixelObj.getRed())&&(pixelObj.getBlue()==otherPixelObj.getBlue())&&(pixelObj.getGreen()==otherPixelObj.getGreen()))
            {
                return true;
            }
        }
    }
    return false;
}

The my art class just creates another image. So it creates another object, and then if the two objects are equal, and the red, green and blue, values are equivalent it returns true. If not it returns false. Thanks for any input!

  • 2
    `I'm getting errors` - what errors do you get? Compile time errors, runtime errors? Any error output / stack trace? Also, what class is `image`? Swing, JavaFX? – Andreas Fester Nov 25 '15 at 10:45
  • 1
    What exception you have got? – Shiladittya Chakraborty Nov 25 '15 at 10:45
  • 2
    " I'm getting errors:" please specify what type of errors – Ramanlfc Nov 25 '15 at 10:45
  • 1
    BTW, in `(pixelObj == otherPixelObj)` you are comparing **object references** which are most likely not identical, hence your `if` condition will never be true. Comparing the colors of each pixel should be sufficient, but depending on the return type of `getRed()` etc. you might need to use `equals()` instead of '==' – Andreas Fester Nov 25 '15 at 10:47
  • 2
    Please explain the errors that you are getting. Meanwhile, you can optimize your equals by introducing fail-safes like checking for equal width and height and size before going pixel by pixel – Serendipity Nov 25 '15 at 10:47
  • 1
    Comparing pixel by pixel is nasty work. If I'd need to do that I'd probably compute SHA hash value for both image sources (byte[]) and compare those. Hitting same hash for different images would be extremely rare. – Jan Nov 25 '15 at 10:50
  • I was given a unit tester for the project we're working on, it's for class, and it can't pass the unit tester. It's not a compile error – LacksCreativity Nov 25 '15 at 10:52
  • And your use case is important as well. If it is merely checking if two images are exactly same, this brute force approach may work, but it will fail even if there is a slight rotation or change in brightness...check other better methods. I see many options [here](http://stackoverflow.com/questions/16602807/programmatically-determine-if-2-images-look-the-same-using-java), [here](http://stackoverflow.com/questions/684713/identifying-2-same-images-using-java) and [here](http://stackoverflow.com/questions/684264/how-does-googles-image-color-search-work/684700#684700) for example. – Serendipity Nov 25 '15 at 10:52
  • So all the unit tester checks is if the image is literally equivalent to itself and my code is returning false. The default constructor was of a kitten, so it passes in the same kitten image to check if they're equivalent and it says they aren't – LacksCreativity Nov 25 '15 at 10:55
  • Andreas Fester, I made the pixelObj.equals(otherPixelObj), and it still returns false. I checked the return types of getRed(), getBlue(), and getGreen(), and they were all int – LacksCreativity Nov 25 '15 at 11:00
  • @Compton - What does the equals method look like in `Pixel`? – Michael Lloyd Lee mlk Nov 25 '15 at 11:09
  • What do you mean? Checking if the two Pixel objects are the same? – LacksCreativity Nov 25 '15 at 11:13
  • When you do `object.equals(somethingElse)` you are calling a method on `object`. This method by default returns `object == somethingElse`. If you have not changed that in `Pixel` then switching between `pixelObj == otherPixelObj` and `pixelObj.equals(otherPixelObj)` will make no difference. – Michael Lloyd Lee mlk Nov 25 '15 at 11:17
  • What do you think about the idea of getting rid of that check and just checking the color values? They're already using the same x and y values, I'm not sure I need to check that the objects, because those objects are just storing the same x and y values – LacksCreativity Nov 25 '15 at 11:22
  • Try it. You have tests to show if you are getting closer to solving the problem. – Michael Lloyd Lee mlk Nov 25 '15 at 11:28
  • For whatever reason, I think that was it. Thanks so much for the help! – LacksCreativity Nov 25 '15 at 11:30

1 Answers1

0

That code will return true if the first pixel (0,0) is the same reference (see pixelObj == otherPixelObj) and does not bother checking the rest. Is that what you want?

I recommend you push the pixels equals up into pixel as it would make the code more readable. I might even push the loop up into the image class.

What tests do you have for this class? Do you have any that use different sized images?

Michael Lloyd Lee mlk
  • 14,561
  • 3
  • 44
  • 81
  • I'm just trying to loop through the x and y values of the image, and check if the pixels are equivalent. If the pixels are equivalent, then the two images must be equivalent. If not, then they're not. Come to think of it, I probably don't even need to check if the pixel objects are equivalent because it's the same x and y values. – LacksCreativity Nov 25 '15 at 11:14