Displaying image metadata with ImageIO

IIOMetadata contains meta information about the image, so not the actual pixels, but stuff like for example compression, keywords, comments, … If you convert from one format to another, you don’t want to loose this information. A ImageTranscoder understands this meta data and maps it onto another format. Internally, Metadata is stored as a bunch of IIOMetadataNodes (they implement the org.w3c.dom.Element interface). The format of this DOM tree is plug-in dependent: the native format (as format features are different), but plug-ins may support the plug-in neutral format. The following example program displays (using the XSLT transformation package) the plug-in neutral format.

Main.java:

import javax.imageio.metadata.*; 
import javax.imageio.stream.*;
import javax.imageio.*;
 
import java.awt.image.*;
import java.util.*;
import java.io.*;
  
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.*;
import javax.xml.parsers.*;
  
import org.w3c.dom.*; 
  
public class Main
{
   public static void main(String []args) throws Exception {
      Iterator readers = ImageIO.getImageReadersByFormatName("png");
      ImageReader reader = (ImageReader) readers.next();
 
      ImageInputStream iis = ImageIO.createImageInputStream(new File("coverpng.png"));
      reader.setInput(iis, true);
      BufferedImage bi = reader.read(0);

      IIOMetadata metadata = reader.getImageMetadata(0);
      Node node = (Node) metadata.getAsTree(metadata.getNativeMetadataFormatName());
 
      // use the XSLT transformation package to output the DOM tree we just created
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      transformer.transform(new DOMSource(node), new StreamResult(System.out));
   }
}

outputs:

<? xml version="1.0" encoding="UTF-8"?>
<javax_imageio_png_1.0>
   <IHDR width="50" height="66" bitDepth="4" colorType="Palette" 
         compressionMethod="deflate" filterMethod="adaptive" 
         interlaceMethod="none"/>
   <PLTE>
      <PLTEEntry index="0" red="0" green="0" blue="0"/>
      <PLTEEntry index="1" red="128" green="192" blue="184"/>
      <PLTEEntry index="2" red="8" green="0" blue="0"/>
      <PLTEEntry index="3" red="248" green="252" blue="248"/>
      <PLTEEntry index="4" red="176" green="176" blue="176"/>
      <PLTEEntry index="5" red="184" green="220" blue="216"/>
      <PLTEEntry index="6" red="120" green="120" blue="120"/>
      <PLTEEntry index="7" red="16" green="152" blue="136"/>
      <PLTEEntry index="8" red="88" green="168" blue="160"/>
      <PLTEEntry index="9" red="72" green="72" blue="72"/>
      <PLTEEntry index="10" red="0" green="0" blue="0"/>
      <PLTEEntry index="11" red="0" green="0" blue="0"/>
      <PLTEEntry index="12" red="0" green="0" blue="0"/>
      <PLTEEntry index="13" red="0" green="0" blue="0"/>
      <PLTEEntry index="14" red="0" green="0" blue="0"/>
      <PLTEEntry index="15" red="0" green="0" blue="0"/>
   </PLTE>
</javax_imageio_png_1.0>

coverpng.png: