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.
Java Advanced Image API (Plugin)<- Looks quite obsolete.
I also found the project in java.net - jai-imageio, but again not maintained for a long time :(- Apache Commons Imaging: Tested in Java: Available Tags for Extracting Metadata Using Apache Commons Imaging
- Sanselan: Tested in Java: Read Exif Metadata Using Sanselan
- metadata-extractor: Testes in Java: Read Exif Metadata Using metadata-extractor
- J-Exiftool
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>
コメント