java - 如何在 Java 中将 GPS 元数据添加到 TIFF?

标签 java gps metadata tiff jai

我正在尝试将 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/

相关文章:

java - Android Studio Java : How to make a button break a while loop

java - 在Android中使用精度标记GPS坐标

algorithm - 数学 - 3d 定位/多点定位

android - 如何解决 "minTime in Android 2.3.4 not working"错误

c# - 如何在Bitmap header中存储ASCII信息?

metadata - 选择页面模板时填充页面元数据架构

java - 开发可扩展的 Twitter 数据适配器

java - 方法重载如何在这里工作?

java - Jhipster 和 Angular 过滤器

javascript - 将图像存储在 Firebase Storage 中并将元数据保存在 Firebase Cloud Firestore(测试版)中