javaexifjavax.imageio

Does ImageIO.read() take EXIF orientation metadata into account?


In JPEG images, EXIF metadata is sometimes included and tells in what orientation the image should be shown.

The question is, whether Java's ImageIO.read() takes EXIF into account while reading a JPEG image, and automatically applies the transformation.

More concretely, if I use Java's ImageIO for converting a JPEG image with EXIF into a PNG image, is the orientation of the PNG image going to be correct? Or is the below code going to produce a PNG image without taking EXIF orientation instructions into account?

private byte[] convertToPng(byte[] imageFileAsByteArray) {
    ByteArrayInputStream bis = new ByteArrayInputStream(imageFileAsByteArray);
    BufferedImage bi = ImageIO.read(bis);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ImageIO.write(bi, "png", bos);

    return bos.toByteArray();
}

Solution

  • The short answer is, unfortunately, no; ImageIO.read(..) (by default) does not take the Exif Orientation tag into account. Your PNG will be not be rotated accordingly.


    However, all ImageIO.read(..) does internally, is to look up an appropriate ImageReader plug-in for the input, and delegate reading to it. And while the JRE-bundled plug-in does not take Exif into account, it is possible to add support for it, in a third-party ImageReader. Unfortunately, I don't know of any that do, but I am considering adding Exif orientation support to the TwelveMonkeys ImageIO JPEGImageReader in the future.

    In the mean time, you have to apply the rotation yourself, by reading the metadata and rotating. The value of the orientation tag can be acquired either using the ImageIO JPEG metadata or some third-party library. I think both the mentioned metadata-extractor or TwelveMonkeys ImageIO can be used for this purpose. JAI ImageIO (using the TIFF metadata) can probably also do this.

    If using the ImageIO JPEG metadata, be aware:

    Note that an application wishing to interpret Exif metadata given a metadata tree structure in the javax_imageio_jpeg_image_1.0 format must check for an unknown marker segment with a tag indicating an APP1 marker and containing data identifying it as an Exif marker segment.