Skip to main content

Inserting data into IIOMetadata

4 replies [Last post]
peterck
Offline
Joined: 2006-05-04
Points: 0

I am trying to modify the metadata of an image using its root node and then merge the changes back into its IIOMetadata class so that the changes can be saved to a new file. The problem I am seeing is that the changes never get merged back into the metadata. Here is my general approach:

1. get the default IIOMetadata object (I am working with tiff images).
2. Get the root node of the metadata (IIOMetadataNode) in the form of a tree structure.
3. Make changes to the root node.
4. Use 'setFromTree' to merge the root node changes back into the IIOMetadata object.

After the merge I then get the root node again and print out the data and find that none of the changes were saved. I have tried merging the data into a completely new IIOMetadata object (instead of back into itself) and it still did not work. This is a new area that I have not worked with, so any suggestions/thoughts would be much appreciated. Thanks.

Here is some example code of my problem:

public static final String NUMBER_ATTR = "number";
    public static final String VALUE_ATTR = "value";
    public static final String TIFF_FIELD_TAG = "TIFFField";
    public static final String TIFF_DOUBLES_TAG = "TIFFDoubles";
    public static final String TIFF_DOUBLE_TAG = "TIFFDouble";
   
    public String path = "C:\\Documents and Settings\\xxx\\My Documents\\My Pictures\\testTiff.TIF";
 

    public void merge() {
        // get a default tiff metadata -- for test purposes the image does
        // not matter, so use any tiff image.
        PlanarImage planarImage = JAI.create("fileload",path);
        BufferedImage bimg = planarImage.getAsBufferedImage();
        Iterator iter = ImageIO.getImageWritersByFormatName("tiff");
        ImageWriter writer = (ImageWriter) iter.next();
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
       
        // get the tiff metadata
        IIOMetadata tiffMetaData = writer.getDefaultImageMetadata(
                new ImageTypeSpecifier(bimg), writeParam);
        // get the metadata root node
        IIOMetadataNode tiffRootNode = (IIOMetadataNode) tiffMetaData
                .getAsTree(tiffMetaData.getNativeMetadataFormatName());

        // make changes to the node...
        tiffRootNode.setAttribute("tagSets","com.sun.media.imageio.plugins.tiff.BaselineTIFFTagSet,com.sun.media.imageio.plugins.tiff.FaxTIFFTagSet,com.sun.media.imageio.plugins.tiff.EXIFParentTIFFTagSet,com.sun.media.imageio.plugins.tiff.GeoTIFFTagSet");
        double[] dValues = {0.1,0.2,0.3,44072.0,9940.2,0.0};
        // this adds in a specific tiff node.
        IIOMetadataNode tiePoint = getModelTiePointsNode(dValues);
        // insert the node in the correct order.
        insertNode(tiffRootNode,tiePoint);
       
        // print out the changes -- ensure that everything is set as it should be...
        printMetaDataNode(tiffRootNode,0);     
       
        try {
            // merge the root node back into the metadata
            tiffMetaData.setFromTree(tiffMetaData.getNativeMetadataFormatName(),tiffRootNode);//"com_sun_media_imageio_plugins_tiff_image_1.0",tiffRootNode);
        } catch (Exception ex) {ex.printStackTrace();}
       
        // print out the node to see if the changes got merged back into the metadata
        System.out.println("\n\n\n\n\nMerged!");
        IIOMetadataNode node = (IIOMetadataNode) tiffMetaData.getAsTree(tiffMetaData.getNativeMetadataFormatName());
        printMetaDataNode(node,0);
    }
   
    // get a node that represents a set of tie points...
    public static IIOMetadataNode getModelTiePointsNode(double[] values) {
        IIOMetadataNode modelTiePointNode = new IIOMetadataNode(TIFF_FIELD_TAG);
        modelTiePointNode.setAttribute("name","ModelTiePointTag");
        modelTiePointNode.setAttribute(NUMBER_ATTR,""+GeoTIFFTagSet.TAG_MODEL_TIE_POINT);
        IIOMetadataNode doublesNode = new IIOMetadataNode(TIFF_DOUBLES_TAG);
        for (int i=0;i<values.length;i++) {
            IIOMetadataNode subNode = new IIOMetadataNode(TIFF_DOUBLE_TAG);
            subNode.setAttribute(VALUE_ATTR,values[i]+"");
            doublesNode.appendChild(subNode);
        }
        modelTiePointNode.appendChild(doublesNode);
        return modelTiePointNode;
    }
   
    //  insert the node (according to its tag order) into the root structure.
    public void insertNode(IIOMetadataNode root, IIOMetadataNode insertingNode) {
        boolean inserted = false;
        //IIOMetadataNode tiffDirectory = getTiffDirectory();
        Node insertNumber = insertingNode.getAttributes().getNamedItem(NUMBER_ATTR);
        int tag = Integer.MAX_VALUE;
        if(insertNumber != null) {
            tag = Integer.parseInt(insertNumber.getNodeValue());
        }       
        // get the children of the node to find where this needs to
        // be inserted.
        NodeList children = root.getElementsByTagName(TIFF_FIELD_TAG);
        for(int i=0; i><children.getLength() && inserted; i++)
        {
            // search through all the TIFF fields to find the one with the
            // given tag value
            Node child = children.item(i);
            Node number = child.getAttributes().getNamedItem(NUMBER_ATTR);
            if(number != null)
            {
                int num = Integer.parseInt(number.getNodeValue());
                if(num > tag)
                {
                    root.insertBefore(insertingNode,child);
                    inserted = true;
                }
            }
        }
        // if the node has not been inserted, then add it to the
        // end of the list.
        if (!inserted) {
            root.appendChild(insertingNode);
        }
    }
   
    // prints out the tree structure...
    public void printMetaDataNode(Node node, int depth) {
        String prefix = "";
        for (int k=0;k<depth;k++) {
            prefix += "  ";
        }
        NodeList list = node.getChildNodes();
        NamedNodeMap nnm = node.getAttributes();
        String name = node.getNodeName();
        System.out.println(prefix+name);
        if (nnm.getLength()>0) {
            System.out.println(prefix+"Attributes:");
            for (int i=0;i<nnm.getLength();i++) {
                Node attNode = nnm.item(i);
                System.out.println(prefix+attNode.getNodeName() + ", " + attNode.getNodeValue());
            }
            System.out.println(prefix+"End Attributes");
        }
        if (list.getLength() > 0) {
            System.out.println(prefix+"Children");
            for (int j=0;j<list.getLength();j++) {
                printMetaDataNode(list.item(j),(depth+1));
            }    
            System.out.println(prefix+"End Children");
        }
    }

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
peterck
Offline
Joined: 2006-05-04
Points: 0

I Figured out my problem. I was trying to add the new nodes directly into the root. Instead it needed to be added after the TIFFIFD. Additionally, I needed to set the tagsets attribute to reflect all tagsets I was adding to the basic tiff structure.

rkmishra
Offline
Joined: 2010-03-20
Points: 0

Hi Peter:

Can you please share your updated code in which you have successfully inserted into IIOMetadata.
Thanks

manchikantisuresh
Offline
Joined: 2010-03-07
Points: 0

Hello sir/madam,

Can i add geotags to tiff image?If you have any idea on this,please guide me.It is very useful for my project.

Thanks in advance.

Stefan E. Funk

Hi there.

You could have a look into the TiffIMP here:

https://develop.sub.uni-goettingen.de/repos/kolibri/trunk/kolibri-base/s...

I wrote it some time ago, but it should not be very much out of date, I hope so...

Cheers.
*fu*

Am 10.04.12 16:54, schrieb :
> Hello sir/madam, Can i add geotags to tiff image?If you have any idea on
> this,please guide me.It is very useful for my project. Thanks in advance.
>