1

I am using this to compare to BufferedImage

private boolean compareImages(BufferedImage actualImage, BufferedImage expectedImage) {
    for (int x = 0; x < expectedImage.getWidth(); x++) {
        for (int y = 0; y < expectedImage.getHeight();y++) {
            if (actualImage.getRGB(x, y) != expectedImage.getRGB(x, y)) {
                return false;
            }
        }
    }
    return true;
}

It works when image type is PNG, but doesn't work when image type is JPEG/JPG

Here is how i have tried to run this code :-`

BufferedImage resizedImage = Scalr.resize(originalImage,50,50);
ImageIO.write(resizedImage,new File("a.jpg"));
BufferedImage bufferedImage = ImageIO.read(new File("a.jpg"));
assertTrue(compareImages(resizedImage, bufferedImage));

This fails for JPG/JPEG and its weird.

PS: I am using this library 'Scalr' to perform resizing of images

Harshil
  • 883
  • 1
  • 8
  • 25
  • 3
    Where do you initialize `actualImage` in `assertTrue(compareImages(actualImage, file));`? And `a.jpg` doesn't work, unless `a` has a `String` field called `jpg`. – Andy Turner Jun 21 '17 at 10:45
  • 1
    What is the purpose of this code? Should it compare straight pixel by pixel (without any epsilon)? If you compare eg. jpg and png created from the same source image, your code will now tell that they are different. Is this the desired behavior? – Krzysztof Cichocki Jun 21 '17 at 10:57
  • @AndyTurner there were multiple typos .. i have corrected them.. – Harshil Jun 21 '17 at 11:15
  • 1
    @KrzysztofCichocki the purpose of this code is to generate a resized JPEG which can be later used in test to make sure the resizing has taken place as expected. Just to add it is not meant to compare cross formats – Harshil Jun 21 '17 at 11:18
  • Your test only tests that the ouput of `ImageIO.read()` should match the input of `ImageIO.write()`.... Whether or not it was correctly (or at all) resized is irrelevant. Are you sure this is what you want to test? As others have mentioned, this will for sure not work with JPEG. If you generate a static image, for later use in tests, the format won't matter, so you might just as well use PNG. And as Krzysztof says, you should probably add some fault tolerance to your comparison (and split into R, G, B and A, and compare each component individually). – Harald K Jun 21 '17 at 12:25

1 Answers1

3

Remember that jpeg is a lossy format, then writing an image to a file in jpeg (say encoding it) may modify the image, so getting it back may not lead to the original one...

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • ohh .. is there any way we can make sure that it doesn't happen ? – Harshil Jun 21 '17 at 11:09
  • 2
    @Harshil don't use jpeg. – Andy Turner Jun 21 '17 at 11:16
  • @Harshil alas no. Even trying to set image quality to 100% cannot guaranty that it will lead to no loss... – Jean-Baptiste Yunès Jun 21 '17 at 11:19
  • I wish i don't have to. But i have to develop this functionality of resizing JPEG/JPG and PNG images. And thus i pretty much can't skip it :( – Harshil Jun 21 '17 at 11:19
  • @Jean-BaptisteYunès okay. i am still trying to figure out some way. What do u think about using ImageWriter ? as mentioned here https://stackoverflow.com/questions/17015197/quality-loss-using-imageio-write – Harshil Jun 21 '17 at 11:22
  • @Jean-BaptisteYunès yes i agree with you totally. But as the code suggests, i am trying to compare the same resized images – Harshil Jun 21 '17 at 11:23
  • @Harshil see https://stackoverflow.com/questions/7982409/is-jpeg-lossless-when-quality-is-set-to-100 and the answer is no... – Jean-Baptiste Yunès Jun 21 '17 at 11:26
  • @Jean-BaptisteYunès okay. so it pretty much looks like pixel by pixel comparison for JPEG/JPG wont work do you have any suggestion on some alternate way to compare BufferedImages just to make sure the output received after resizing is good ? – Harshil Jun 21 '17 at 11:35