Java ImageIO,无法更改元数据树

标签 java metadata jpeg comments 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);

方法 getCommentFromDOM() 只是遍历树并获取 com 标记中的评论属性,然后它更改评论字段但返回原始值。

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

所以当这个程序被执行时它会输出:

  comment 1 = originalcomment
  comment 2 = FOOOOOOOOOOO
  comment 3 = originalcomment

因此 DOM 已更改,但看起来 meta.setFromTree() 方法没有使用新树。我也试过运行 meta.reset() 应该清除元数据,但这似乎对元对象也没有影响。

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

最佳答案

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);

关于Java ImageIO,无法更改元数据树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8428387/

相关文章:

java - 优雅地结束基于控制台的多线程程序

java - java应用程序中无限循环的内存不足和stackoverflow异常

Java 模运算符优先级

java - 树遍历

asp.net-mvc-4 - ModelMetadata.FromStringExpression 不适用于嵌套属性

Java - 复制 JPG 同时保留所有文件属性

javax.imageio.IIOException : Invalid icc profile: duplicate sequence numbers

java - 将两个整数附加到十六进制,每个整数代表一个半字节。数字

java - 批处理、解析和转换 .1sc 文件中的元数据

video - 获取 MOV 视频的元数据