Copying image and maintain orientation?

Viewed 536

Edit It turns out that the 2nd snippet is actually working but the images in question still show incorrectly in my IDE (IntelliJ IDEA) for some reason.

I am trying read an image, place a watermark and save it in a different folder and the below code does a good job, but it randomly orientates my images.

    try {
        final Image image = ImageIO.read(file);
        int w = ((BufferedImage) image).getWidth();
        int h = ((BufferedImage) image).getHeight();

        final BufferedImage finalImage = 
            new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

        //Graphics2D g = finalImage.createGraphics();
        Graphics2D g = (Graphics2D) finalImage.getGraphics();
        g.drawImage(image, 0, 0, null);
        g.drawImage(watermark, 0, 0, null);
        g.dispose();

        File outputFile = new File("watermarked/" + folderName + "/" + file.getName());
        outputFile.mkdirs();

        ImageIO.write(finalImage, "jpg", outputFile);


    } catch (IOException e) {
        // TODO: notify client
        e.printStackTrace();
    }

After some reading I learned that ImageIO.read(...) does not maintain orientation or other "metadata" of the image it is processing. I also read about using the ImageReader to extract the metadata. According to the docs, using ImageReader.readall() should include the metadata in the returned IIOImage but I still end up with some of my images upside down. The below code demonstrates the copying without adding a watermark.

    File out = new File("watermarked/" + folderName + "/" + file.getName());
    out.getParentFile().mkdirs();

    ImageInputStream input = ImageIO.createImageInputStream(file);
    ImageOutputStream output = ImageIO.createImageOutputStream(out);

    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
    ImageReader reader = readers.next();
    reader.setInput(input);

    IIOImage image = reader.readAll(0, null);
    // Should not be needed since readAll should already take care of it.
    IIOMetadata metadata = reader.getImageMetadata(0);
    image.setMetadata(metadata);

    ImageWriter writer = ImageIO.getImageWriter(reader);
    writer.setOutput(output);
    writer.write(image);


    System.out.println(writer.canReplaceImageMetadata(0)); // Returns false
    writer.replaceImageMetadata(0, metadata); // Results in a "Unsupported write variant" error.

Both code snippets reside in a method that get passed a folderName as a string and the actual image file.

Edit

The above snippet works and the issue is something else. In my windows folder all my images made with a Galaxy S8 show in the correct orientation. But when I copy them to my project and open them in IntelliJ IDEA some are oriented differently. So I added sanselan as a dependency to get more insight in the meta data of the images and the images that get a different orientation in the IDE do indeed show a different orientation in the metadata. But why aren't they oriented like that in the windows folder, am I missing a metadata field or is windows storing additional data somewhere outside the image metadata?

0 Answers
Related