I'm trying to use ImageIO to change the JPEG Comment field (COM) of a file. I read the metadata, do some changes to the DOM (change attribute of the comment field), then save / print the metadata. But my changes are not shown. This is the code (in a simple test class with static main()), 'file' is set.
ImageWriter writer = ImageIO.getImageWritersBySuffix("jpeg").next();
ImageReader reader = ImageIO.getImageReader(writer);
reader.setInput(new FileImageInputStream(file));
RenderedImage img = reader.read(0);
IIOMetadata meta = reader.getImageMetadata(0);
IIOMetadataNode root1 = (IIOMetadataNode) meta.getAsTree("javax_imageio_jpeg_image_1.0");
String comment1 = getCommentFromDOM(root1);
System.out.println("comment 1 = " + comment1);
String comment2 = getCommentFromDOM(root1);
System.out.println("comment 2 = " + comment2);
meta.setFromTree("javax_imageio_jpeg_image_1.0", root1);
//meta.reset();
IIOMetadataNode root2 = (IIOMetadataNode) meta.getAsTree("javax_imageio_jpeg_image_1.0");
String comment3 = getCommentFromDOM(root2);
System.out.println("comment 3 = " + comment3);
The method getCommentFromDOM() just goes trough the tree and gets the comment attribute in the com tag, and then it changes the comment field but returns the original value.
...
if(md.getNodeName().equalsIgnoreCase("com")) {
String comment = md.getAttribute("comment");
md.setAttribute("comment", "FOOOOOOOOOO");
return comment;
}
...
So when this program is executed it will output:
comment 1 = originalcomment comment 2 = FOOOOOOOOOOO comment 3 = originalcomment
So the DOM was changed, but it looks like the meta.setFromTree() method did not use the new tree. I've also tried running meta.reset() which should clear the metadata, but that also seems to have no effect on the meta object.
Can anyone see what I've done wrong in this very simple ImageIO test?
nowaq's answer got me started in the right direction, but I was having trouble handling the case where the original image did not have an existing comment (his solution works in case the original already has a comment). The following code works for me in both cases:
Element tree = (Element) imageMetadata.getAsTree("javax_imageio_jpeg_image_1.0");
NodeList comNL = tree.getElementsByTagName("com");
IIOMetadataNode comNode;
if (comNL.getLength() == 0) {
comNode = new IIOMetadataNode("com");
Node markerSequenceNode = tree.getElementsByTagName("markerSequence").item(0);
markerSequenceNode.insertBefore(comNode,markerSequenceNode.getFirstChild());
} else {
comNode = (IIOMetadataNode) comNL.item(0);
}
comNode.setUserObject(("YourComment").getBytes("ISO-8859-1"));
imageMetadata.setFromTree("javax_imageio_jpeg_image_1.0", tree);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With