1

I am trying to write text on top of a BufferedImage, then do pixel by pixel comparison with an identical image. However, the comparison always fails. My code looks as follows:

    BufferedImage referenceImage = ImageIO.read(new File("reference.jpg"));
    BufferedImage image = ImageIO.read(new File("base_image.jpg"));
    image.createGraphics().drawString("hello world", 10, 10);
    //ImageIO.write(image, "jpg", new File("newimage.jpg"));
    //image = ImageIO.read(new File("newimage.jpg"));
    assertEquals(image.getWidth(), referenceImage.getWidth());
    assertEquals(image.getHeight(), referenceImage.getHeight());
    boolean identicalImages = true;
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            if (image.getRGB(x, y) != referenceImage.getRGB(x, y)) {
                identicalImages = false;
            }
        }
    }
    assertTrue(identicalImages);

However, if I uncomment the two commented lines, the code works as expected. I am suspecting it's something that has to do with buffers that need flushing. I tried to flush the image object, but no luck. If anyone could shed some light on what's happening and how to get it to work without having to write the image to disk then read it back, that'd be awesome.

turingcomplete
  • 2,128
  • 3
  • 16
  • 25
  • 1
    Assign the result of `BufferedImage#createGraphics` to a variable, do your painting, when you're done, call `Graphics#dispose` - not sure if will make a difference, but you should get into the habit of "disposing" of what you "create" – MadProgrammer Jun 29 '17 at 12:36
  • What happens if you load the same file in the first two lines? – Steve Smith Jun 29 '17 at 13:15
  • maybe the string youre drawing is the same color as the image background – Tom K Jun 29 '17 at 13:30
  • @TomK base image is just a background image, reference_image is base_image with text drawn on top. They are both identical after I add the text to the base image, but the pixel by pixel comparison fails unless I save the image and reread it – turingcomplete Jun 29 '17 at 14:10
  • @turingcomplete when you say it fails, do you mean that `identicalImages` is true in the end? – Tom K Jun 29 '17 at 14:55
  • @TomK identicalImages comes out as false in the end. – turingcomplete Jun 29 '17 at 14:59

1 Answers1

1

The reason the images are only the same after saving/loading, is because after that, both images have been affected by the (lossy) jpeg conversion. Prior to that, the text written to base_image has not been "converted".

Steve Smith
  • 2,244
  • 2
  • 18
  • 22
  • base image is just a background image, reference_image is base_image with text drawn on top. They are both identical after I add the text to the base image, but the pixel by pixel comparison fails unless I save the image and reread it – turingcomplete Jun 29 '17 at 14:10
  • @turingcomplete To clarify, you're writing the text on `base_image`, which should then make it the same as reference_image which already has the text? What are the values of x & y when `identicalImages` is set to false? How do you know they are both identical if your pixel comparison fails? – Steve Smith Jun 29 '17 at 14:28
  • Yes, you are correct. The they are both identical because reference_image was generated the same way as the image I am generating in the code. If I save the image to disk after writing the text then rereading, then the pixel by pixel comparison passes. – turingcomplete Jun 29 '17 at 14:40
  • 1
    @turingcomplete I think the reason the images are only the same after saving/loading, is because it is only after that that both images have been affected by the (lossy) jpeg conversion. – Steve Smith Jun 29 '17 at 14:45
  • I agree with your assessment @SteveSmith. The problem is the JPEG lossy compression. The OP might want to experiment with the source code in [this answer](https://stackoverflow.com/a/5998015/418556) to see the effect of different levels of JPEG compression. – Andrew Thompson Jun 30 '17 at 03:29