Created
May 13, 2013 04:17
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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