package edu.mbl.jif.imaging; // ^^^^^ GBH: This uses JAI, not ImageIO... import edu.mbl.jif.imaging.meta.XML2JTree; import com.sun.media.imageio.plugins.tiff.*; import org.w3c.dom.*; import java.awt.*; import java.awt.image.renderable.*; import java.io.*; import java.util.*; import javax.imageio.*; import javax.imageio.metadata.*; import javax.imageio.stream.*; import javax.media.jai.*; // displays metadata in edu.mbl.jif.xml.XML2JTree public class TiffMetadataTreeTest { public TiffMetadataTreeTest() {} // static String tiffFileIn = "C:\\_dev\\_TestImages\\ImagesTest\\tiff\\new_zealand.tif"; static String tiffFileout = "C:\\_dev\\_TestImages\\testMeta.tif"; // //--------------------------------------------------------------------- public static void writeMeta(String filename) { String nameOfOutputFile = tiffFileout; //will set to args[0] String errorMessage = null; //check arguments, set nameOfOutputFile // if (args.length != 1) { // errorMessage = "I take one argument, name of output tiff."; // } else if ((new File(nameOfOutputFile = args[0])).exists()) { // errorMessage = "Won't clobber" + nameOfOutputFile; // } // if (errorMessage != null) { // System.out.println(errorMessage); // System.exit(0); // } //Make a blue rectangle Byte[] bandValues = {new Byte((byte) 100), new Byte((byte) 100), new Byte((byte) 200) }; RenderedOp constantImage = JAI.create("constant", (new ParameterBlock()).add(new Float(300)).add(new Float(500)).add(bandValues)); //Now we set about saving the blue image as a tiff, with the //Tiff tag "ImageDescription" set to "Hello World. The tiff will be // untiled so the tiff can be opened by Photoshop. //In Photoshop, this tag is File >> File Info >> General >> Caption. //I'll use an "imageWrite" RenderedOp (com.sun.media.jai.operator.ImageWriteDescriptor). ParameterBlock writePB = new ParameterBlock().addSource(constantImage); //Set 'Output' and 'Format'. writePB.add(nameOfOutputFile).add("tiff"); //Set 'UseProperties', 'Transcode', 'VerifyOutput' and // 'AllowPixelReplacement' to default. writePB.add(new Boolean(true)).add(new Boolean(true)).add(new Boolean(true)).add(new Boolean(false)); //Set 'TileSize' so as to make one big tile (for an untiled tiff). Dimension tileDim = new Dimension(constantImage.getWidth(), constantImage.getHeight()); writePB.add(tileDim); //Set 'streamMetadata' to default. writePB.add(null); //Use first available ImageWriter that can handle a tiff. Iterator tiffWriters = ImageIO.getImageWritersBySuffix("tiff"); ImageWriter tiffWriter = (ImageWriter) tiffWriters.next(); System.out.print("Using this tiff writer: "); System.out.println(tiffWriter.toString()); //Use a generic parameters for the imagewriter. ImageWriteParam writeParam = tiffWriter.getDefaultWriteParam(); //Get default Metadata for an image in a tiff. ImageTypeSpecifier thisType = new ImageTypeSpecifier(constantImage.getColorModel(), constantImage.getSampleModel()); IIOMetadata imageData = tiffWriter.getDefaultImageMetadata(thisType, writeParam); //Verify we're stuck with native tiff metadata format. //Not as expected, c.f. the second table in //http://java.sun.com/products/java-media/jai/forDevelopers/jai-imageio-1_0-rc-docs/index.html System.out.print("Standard metadata format is available: "); System.out.println(String.valueOf(imageData.isStandardMetadataFormatSupported())); //Get the name for the native format. String imageDataFormat = imageData.getNativeMetadataFormatName(); //Turn the metadata object into a tree. Node iNode = imageData.getAsTree(imageDataFormat); // addTIFFAsciiField(String tagNumber, String Name, String value){ //Create the little tree corresponding to the Tiff Tag "ImageDescription". IIOMetadataNode fieldNode = new IIOMetadataNode("TIFFField"); fieldNode.setAttribute("number", "270"); fieldNode.setAttribute("name", "ImageDescription"); //fieldNode.setAttribute("number", "269"); //fieldNode.setAttribute("name", "DocumentName"); IIOMetadataNode asciisNode = new IIOMetadataNode("TIFFAsciis"); fieldNode.appendChild(asciisNode); IIOMetadataNode asciiNode = new IIOMetadataNode("TIFFAscii"); String s = "PSj:type=polstack;frames=5;exposure=3000;"; asciiNode.setAttribute("value", s); asciisNode.appendChild(asciiNode); //Add this to the image metadata tree, down one level. Node tagSetNode = iNode.getFirstChild(); tagSetNode.appendChild(fieldNode); //Convert the tree back to metadata object try { imageData.setFromTree(imageDataFormat, iNode); } catch (IIOInvalidTreeException e) { System.out.println(e.getOffendingNode().toString()); System.exit(0); } //Set 'ImageMetadata' to resulting metadata object. writePB.add(imageData); //Set 'Thumbnails', 'Listeners' and 'Locale' to default. writePB.add(null).add(null).add(null); //Set 'WriteParam' and 'Writer'. writePB.add(writeParam).add(tiffWriter); //At last, we save the file. JAI.create("imageWrite", writePB); } // //--------------------------------------------------------------------- public static void viewMeta(String filename) { String nameOfInputFile = filename; //tiffFileIn; //will set to args[0] String errorMessage = null; //check arguments, set nameOfInputFile try { //make input stream. File inFile = new File(nameOfInputFile); ImageInputStream inStream = ImageIO.createImageInputStream(inFile); //Fetch first available tiff reader. Iterator readerList = ImageIO.getImageReaders(inStream); ImageReader firstReader = (ImageReader) readerList.next(); System.out.println(firstReader.toString()); //attach reader and stream. firstReader.setInput(inStream); // get Stream Metadata IIOMetadata mdataS = null; Node mNodeS = null; try { mdataS = firstReader.getStreamMetadata(); mNodeS = mdataS.getAsTree(mdataS.getNativeMetadataFormatName()); edu.mbl.jif.gui.test.FrameForTest f = new edu.mbl.jif.gui.test.FrameForTest(); f.setTitle("Stream Metadata"); f.getContentPane().add( new XML2JTree( mNodeS, true ),BorderLayout.CENTER); f.pack(); f.setVisible(true); displayMetadata(mNodeS); } catch (Exception e) { e.printStackTrace(); } //This should read read the metadata attached to first image, // w/o reading that image. IIOMetadata mdata = firstReader.getImageMetadata(0); //Convert from metadata object to a tree Node mNode = mdata.getAsTree(mdata.getNativeMetadataFormatName()); edu.mbl.jif.gui.test.FrameForTest fi = new edu.mbl.jif.gui.test.FrameForTest(); fi.setTitle("Image Metadata"); fi.getContentPane().add( new XML2JTree( mNode, true ),BorderLayout.CENTER); fi.pack(); fi.setVisible(true); //print out the metadata. displayMetadata(mNode); } catch (Exception e) { System.out.println("Caught: " + e.toString()); System.exit(0); } } static void displayMetadata(Node root) { displayMetadata(root, 0); } //--------------------------------------------------------------------- static void displayMetadata(Node node, int level) { indent(level); // emit open tag System.out.print("<" + node.getNodeName()); NamedNodeMap map = node.getAttributes(); if (map != null) { // print attribute values int length = map.getLength(); for (int i = 0; i < length; i++) { Node attr = map.item(i); System.out.print(" " + attr.getNodeName() + "=\"" + attr.getNodeValue() + "\""); } } Node child = node.getFirstChild(); if (child != null) { System.out.println(">"); // close current tag while (child != null) { // emit child tags recursively displayMetadata(child, level + 1); child = child.getNextSibling(); } indent(level); // emit close tag System.out.println("</" + node.getNodeName() + ">"); } else { System.out.println("/>"); } } //--------------------------------------------------------------------- static void indent(int level) { for (int i = 0; i < level; i++) { System.out.print(" "); } } public static void main(String[] args) { // String imageFile = edu.mbl.jif.Constants.testDataPath + "meta/ome.tif"; String imageFile = "C:/_Dev/_Dev_Data/TestImages/testData/meta/OME-Tiff.tif"; viewMeta(imageFile); } }