Java ImageIO,无法更改元数据树

klo*_*ogd 3 java jpeg comments metadata javax.imageio

我正在尝试使用ImageIO来更改文件的JPEG注释字段(COM).我读取了元数据,对DOM进行了一些更改(注释字段的更改属性),然后保存/打印元数据.但我没有显示我的更改.这是代码(在带有静态main()的简单测试类中),设置了'file'.

        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);
Run Code Online (Sandbox Code Playgroud)

方法getCommentFromDOM()只是通过树并获取com标记中的comment属性,然后它更改注释字段但返回原始值.

             ...
                if(md.getNodeName().equalsIgnoreCase("com")) {
                    String comment = md.getAttribute("comment");
                    md.setAttribute("comment", "FOOOOOOOOOO");
                    return comment;
                }
             ...
Run Code Online (Sandbox Code Playgroud)

因此,当执行该程序时,它将输出:

  comment 1 = originalcomment
  comment 2 = FOOOOOOOOOOO
  comment 3 = originalcomment
Run Code Online (Sandbox Code Playgroud)

所以DOM被改变了,但看起来meta.setFromTree()方法没有使用新树.我也尝试过运行meta.reset(),它应该清除元数据,但这似乎对元对象没有任何影响.

在这个非常简单的ImageIO测试中,谁能看到我做错了什么?

Jos*_*son 5

nowaq的回答让我开始朝着正确的方向前进,但是我在处理原始图像没有现有注释的情况下遇到了问题(他的解决方案适用于原来已经有评论的情况).在以下两种情况下,以下代码适用于我:

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);
Run Code Online (Sandbox Code Playgroud)