スキップしてメイン コンテンツに移動

Java: Read Image Metadata by Java Image IO

Introduction

I have googled and wrote small code snippet for parsing and printing image metadata in Java.
The biggest problem of this program (or maybe Java standard imageio library) cannot read jpeg exif data.
I have found following solutions for this problem.

Both libraries are not updated recently but I guess it's because they don't need anymore enhancements.
I will investigate and re-post how to use these image libraries soon...

In this post, I only show you the code snippet for parsing and printing image metadata using Java standard Image API which Oracle provides.

Code

package com.dukesoftware.utils.image;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Node;

public class ImageMetaDataReader {

    public static void main(String[] args) throws Exception {
        printMetaDataAsXml(new File("c:/temp/metada_eample.jpg"));
    }

    public static void printMetaDataAsXml(File file) throws IOException, TransformerException {
        try (ImageInputStream iis = ImageIO.createImageInputStream(file)) {
            ImageReader reader = getImageReader(iis);

            // read metadata of first image
            IIOMetadata metadata = reader.getImageMetadata(0);

            for (String name : metadata.getMetadataFormatNames()) {
                System.out.println("Format name: " + name);
                System.out.println(toString(metadata.getAsTree(name)));
            }
        }
    }

    private static ImageReader getImageReader(ImageInputStream iis) {
        Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
        
        return selectFirstReader(readers, iis);
    }

    private static ImageReader selectFirstReader(Iterator<ImageReader> readers, ImageInputStream iis)
    throws IllegalArgumentException {
        if (!readers.hasNext()) throw new IllegalArgumentException("No reader found");
            
        ImageReader reader = readers.next();

        reader.setInput(iis, true);

        return reader;
    }

    public static String toString(Node node) throws TransformerException {
        StringWriter writer = new StringWriter();
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.transform(new DOMSource(node), new StreamResult(writer));
        return writer.toString();
    }

}

Example Result of Extracting Image Metadata

I have run the above program against following image.


The metadata xml formatted result corresponding to the image is below.

Format name: javax_imageio_jpeg_image_1.0
<?xml version="1.0" encoding="UTF-8"?><javax_imageio_jpeg_image_1.0>
<JPEGvariety>
<app0JFIF majorVersion="1" minorVersion="1" resUnits="1" Xdensity="96" Ydensity="96" thumbWidth="0" thumbHeight="0"/>
</JPEGvariety>
<markerSequence>
<unknown MarkerTag="225"/>
<unknown MarkerTag="225"/>
<unknown MarkerTag="237"/>
<dqt>
<dqtable elementPrecision="0" qtableId="0"/>
</dqt>
<dqt>
<dqtable elementPrecision="0" qtableId="1"/>
</dqt>
<sof process="0" samplePrecision="8" numLines="1440" samplesPerLine="1440" numFrameComponents="3">
<componentSpec componentId="1" HsamplingFactor="1" VsamplingFactor="1" QtableSelector="0"/>
<componentSpec componentId="2" HsamplingFactor="1" VsamplingFactor="1" QtableSelector="1"/>
<componentSpec componentId="3" HsamplingFactor="1" VsamplingFactor="1" QtableSelector="1"/>
</sof>
<dht>
<dhtable class="0" htableId="0"/>
</dht>
<dht>
<dhtable class="1" htableId="0"/>
</dht>
<dht>
<dhtable class="0" htableId="1"/>
</dht>
<dht>
<dhtable class="1" htableId="1"/>
</dht>
<sos numScanComponents="3" startSpectralSelection="0" endSpectralSelection="63" approxHigh="0" approxLow="0">
<scanComponentSpec componentSelector="1" dcHuffTable="0" acHuffTable="0"/>
<scanComponentSpec componentSelector="2" dcHuffTable="1" acHuffTable="1"/>
<scanComponentSpec componentSelector="3" dcHuffTable="1" acHuffTable="1"/>
</sos>
</markerSequence>
</javax_imageio_jpeg_image_1.0>

Format name: javax_imageio_1.0
<?xml version="1.0" encoding="UTF-8"?><javax_imageio_1.0>
<Chroma>
<ColorSpaceType name="YCbCr"/>
<NumChannels value="3"/>
</Chroma>
<Compression>
<CompressionTypeName value="JPEG"/>
<Lossless value="FALSE"/>
<NumProgressiveScans value="1"/>
</Compression>
<Dimension>
<PixelAspectRatio value="1.0"/>
<ImageOrientation value="normal"/>
<HorizontalPixelSize value="0.26458332"/>
<VerticalPixelSize value="0.26458332"/>
</Dimension>
</javax_imageio_1.0>

コメント