Search code examples
javametadataexifiptcmetadata-extractor

Metadata extractor java doesn't extract exif or iptc


I am trying to get the exif of a jpeg image but it doesn't work. First I read my image using BufferedImage and I convert it to a file and then I apply the same code as here: https://code.google.com/p/metadata-extractor/source/browse/Samples/com/drew/metadata/SampleUsage.java?name=2.5.1. What am I doing wrong? Why does the JpegSegmentReader.SEGMENT_APP1 returns null?

    File outfile = new File("image.jpg");
    ImageIO.write(imagine, "jpg", outfile);
    try{
            JpegSegmentReader segmentReader = new JpegSegmentReader(outfile);
            byte[] exifSegment = segmentReader.readSegment(JpegSegmentReader.SEGMENT_APP1);
            System.out.println(Arrays.toString(segmentReader.readSegment(JpegSegmentReader.SEGMENT_APP1)));
            byte[] iptcSegment = segmentReader.readSegment(JpegSegmentReader.SEGMENT_APPD);
            Metadata metadata = new Metadata();
            if (exifSegment != null)
                new ExifReader().extract(new ByteArrayReader(exifSegment), metadata);
            if (iptcSegment != null)
                new IptcReader().extract(new ByteArrayReader(iptcSegment), metadata);
            printImageTags(metadata);
        }catch (JpegProcessingException e) {
            System.err.println("error 3a: " + e);
        }

Solution

  • ImageIO.write() doesn't write Exif metadata* (APP1/Exif). It only stores JFIF (for more information on Exif/JFIF, see JPEG on WikiPedia) in the APP0 segment. Because of this, there will never be an APP1 segment in your code.

    There's also no Exif metadata available in the BufferedImage or RenderedImage that you are writing, as objects of these types only contain pixel data.

    If you want to extract Exif metadata, you need to find a reference to the original file you read the image (imagine) from, and read from there.

    *) ImageIO and the standard JPEGImageWriter can write Exif metadata, but only if you pass the Exif metadata to the writer, using the IIOMetadata API. But I don't think this is relevant for your use case.