我正在尝试将 GPS 数据添加到我用 Java 创建的 TIFF 文件中。我正在使用 JAI-ImageIO 库,尽管如果有更好的库来处理 GPS 元数据和自定义元数据,我愿意研究它。
我试图将 GPS 元数据直接添加到节点,但它似乎剥离了 GPS IDF 标签。我试图将 GPS IFD 添加到 TIFFIFD 对象(来自 TIFFIMageMetadata 对象),但这似乎无法正确保存数据。
基本上,我正在努力让它正确地保存 GPS 数据,并试图弄清楚如何在其中获取数据。在 Internet 上搜索数小时后,几乎没有得到任何教程或帮助,而且我在 Stack Overflow 上也看不到任何有用的信息,但我的搜索能力可能有所欠缺。
我尝试通过直接操作元数据节点来实现的一些代码:
RenderedImage img = generateImageSomehow();
File writeTarget = new File("blah.tiff");
//Get the image writer
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
ImageTypeSpecifier specifier = new ImageTypeSpecifier(renderedImage);
ImageWriter writer = writers.next();
//Get the metadata
IIOMetadata metadata = writer.getDefaultImageMetadata(specifier, writers.getDefaultWriteParam());
Node root = metadata.getAsTree(FileConstants.TIFF_METADATA_FORMAT);
Node ifd = root.getFirstChild();
//Create a new IFD node for the GPS data, and add some GPS data to it
IIOMetadataNode gpsRootNode = new IIOMetadataNode("TIFFIFD");
gpsRootNode.setAttribute(FileConstants.TIFF_FIELD_NUMBER_ATTRIBUTE, "34853");
gpsRootNode.setAttribute(FileConstants.TIFF_FIELD_NAME_ATTRIBUTE, "GPS");
gpsRootNode.setAttribute("tagSets", "com.sun.media.imageio.plugins.tiff.EXIFGPSTagSet");
IIOMetadataNode childNode = new IIOMetadataNode(FileConstants.TIFF_FIELD_TAG);
childNode.setAttribute(FileConstants.TIFF_FIELD_NUMBER_ATTRIBUTE, "1");
childNode.setAttribute(FileConstants.TIFF_FIELD_NAME_ATTRIBUTE, "GPSLatitudeRef");
IIOMetadataNode asciiNode = new IIOMetadataNode("TIFFAsciis");
IIOMetadataNode childAsciiNode = new IIOMetadataNode("TIFFAscii");
childAsciiNode.setAttribute(FileConstants.TIFF_FIELD_VALUE_ATTRIBUTE, "N");
asciiNode.appendChild(childAsciiNode);
childNode.appendChild(asciiNode);
gpsRootNode.appendChild(childNode);
ifd.appendChild(gpsRootNode);
//Update metadata with new tree
metadata.setFromTree(FileConstants.TIFF_METADATA_FORMAT, root);
ImageOutputStream outstr = ImageIO.createImageOutputStream(writeTarget);
writer.setOutput(outstr);
//Write the image
IIOImage img = new IIOImage(renderedImage, Collections.<BufferedImage> emptyList(), metadata);
writer.write(img);
outstr.close();
我正在尝试加入 GPS 根节点,以及一个(当前硬编码的)方向值。我是不是在错误的层次、错误的地方、错误的方式等等?我很好地这样做 - 尽管使用 TIFF 对象可能更好。
已更新以添加额外的代码,以展示我如何创建图像以及如何保存它。
预计到达时间:
这里是这一行:
ifd.appendChild(gpsRootNode);
实际上应该是:
root.appendChild(gpsRootNode);
这是我正在尝试的事情,但是当我将 ifd 节点作为添加 GPS 节点的节点时,出现异常:
Exception in thread "Thread-2" java.lang.ClassCastException: com.sun.media.imageioimpl.plugins.tiff.TIFFIFD cannot be cast to [J
不确定那里是否有预期 - 看起来它正在尝试将 IFD 节点转换为 Long 数组(根据标准 JNI 类型) - 当我将它附加到根时,它似乎只是从中删除它元数据节点。
最佳答案
问题很可能是您正在操作的元数据树表示只是一个工作副本。当您稍后编写图像并将其传递给元数据
时,您对树表示的更改将丢失。
用您的 GPS 特定标签更新元数据树 (root
) 后,您必须调用 metadata.setFromTree(TIFF_METADATA_FORMAT, root)
或 metadata.mergeTree(TIFF_METADATA_FORMAT, root)
将您的更改设置/合并回 metadata
实例。当您开始使用 metadata.getAsTree(..)
而不是空结构时,您可能想要使用 setFromTree(..)
。
PS:如果这不是问题所在,请添加更新元数据和写入图像的代码。 :-)
关于java - 如何在 Java 中将 GPS 元数据添加到 TIFF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19371620/