Skip to content

Instantly share code, notes, and snippets.

@favila
Created May 13, 2013 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save favila/5566125 to your computer and use it in GitHub Desktop.
Save favila/5566125 to your computer and use it in GitHub Desktop.
Sample code demonstrating how to parse the XMP metadata in an image using javax.imageio.metadata. Written to answer this stackoverflow question: http://stackoverflow.com/a/13748517/1002469
import java.io.*;
import java.util.*;
// for imageio metadata
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.imageio.metadata.*;
// for xml handling
import org.w3c.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.parsers.*;
public class imgmeta {
// Very lazy exception handling
// This is just a quick example
public static void main(String[] args) throws Exception {
String filename = args[0];
File file = new File(filename);
ImageInputStream imagestream = ImageIO.createImageInputStream(file);
// get a reader which is able to read this file
Iterator<ImageReader> readers = ImageIO.getImageReaders(imagestream);
ImageReader reader = readers.next();
// feed image to reader
reader.setInput(imagestream, true);
// get metadata of first image
IIOMetadata metadata = reader.getImageMetadata(0);
// get any metadata format name
// (you should prefer the native one, but not all images have one)
// String mdataname = metadata.getNativeMetadataFormatName(); // might be null
String[] mdatanames = metadata.getMetadataFormatNames();
String mdataname = mdatanames[0];
Element metadatadom = (Element) metadata.getAsTree(mdataname);
// String metadata_in_xml = xmlToString(metadatadom);
// now print it:
Document xmp = getXMP(metadatadom);
System.out.print(transformXML(xmp));
}
public static String transformXML(Node xml) throws Exception {
// now let's serialize to an XML string
// javax.xml.transform.Transformer takes xml sources
// in one representation and transforms them to xml
// in another representation
// Representations include: DOM, JAXB, SAX, stream, etc
StringWriter writer = new StringWriter();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(xml), new StreamResult(writer));
return writer.toString();
}
public static Document transformXML(String xml) throws Exception {
StringReader reader = new StringReader(xml);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new StreamSource(reader), new DOMResult(doc));
return doc;
}
public static Document getXMP(Element metadata_dom) throws Exception {
// There are many more robust ways of selecting nodes
// (e.g. javax.xml.xpath), but this is for a simple example
// that only uses the native DOM methods
// This is very brittle because we're making assumptions about
// the metadata_dom structure. There are two sources of brittleness:
// 1. The metadata format from `metadata.getMetadataFormatNames()`.
// You should probably settle on a standard one you know will
// exist, like 'javax_imageio_1.0'
// 2. How the image stores the metadata. Usually XMP data will
// be in a text field with keyword 'XML:com.adobe.xmp', but
// I don't know that this is *always* the case.
// the code below assumes "javax_imageio_png_1.0" format
NodeList iTXtEntries = metadata_dom.getElementsByTagName("iTXtEntry");
Element iTXtEntry = null;
Element entry = null;
for (int i = 0; i < iTXtEntries.getLength(); i++) {
entry = (Element) iTXtEntries.item(i);
// System.out.print(entry.getAttribute("keyword")+"\n");
// System.out.print(com_adobe_xmp+"\n");
if (entry.getAttribute("keyword").equals("XML:com.adobe.xmp")) {
iTXtEntry = entry;
break;
}
}
if (iTXtEntry == null) {
return null;
}
String xmp_xml_doc = iTXtEntry.getAttribute("text");
// xmp_xml_doc is now an xml document string
// If you want to parse it as an XML document, use an XML
// parser.
Document xmp_doc = transformXML(xmp_xml_doc);
return xmp_doc;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment