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

我正在尝试将GPS数据添加到我用Java创建的TIFF文件中。 我正在使用JAI-ImageIO库,虽然如果有更好的库来同时执行G​​PS元数据和自定义元数据,我愿意研究它。

我试图直接将GPS元数据添加到节点,但它似乎剥离了GPS IDF标签。 我试图将GPS IFD添加到TIFFIFD对象(来自TIFFIMageMetadata对象),但这似乎并没有正确保存数据。

基本上,我正在努力让它正确地保存GPS数据,并试图弄清楚如何在那里获取数据。 在互联网上搜索的时间几乎没有产生任何教程或帮助,我没有看到任何有用的Stack Overflow,但我的搜索能力可能缺乏。

我尝试通过直接操作元数据节点来完成一些代码:

RenderedImage img = generateImageSomehow(); File writeTarget = new File("blah.tiff"); //Get the image writer Iterator 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. emptyList(), metadata); writer.write(img); outstr.close(); 

我正在尝试加入GPS根节点,以及方向的(当前硬编码的)值。 我是在错误的地方,在错误的地方,以错误的方式附着等等吗? 我这样做很好 – 尽管使用TIFF对象可能更好。

更新以添加其他代码,以显示我如何创建图像,以及我如何保存它。


ETA:

这一行在这里:

 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类型) – 当我将它附加到根时,它似乎只是从元数据节点中删除它。

问题很可能是您正在操作的元数据树表示只是一个工作副本。 稍后编写图像并将其传递给metadata ,对树表示的更改将丢失。

使用GPS特定标记更新元数据树( root )后,您必须调用metadata.setFromTree(TIFF_METADATA_FORMAT, root)metadata.mergeTree(TIFF_METADATA_FORMAT, root)以将更改设置/合并回metadata实例。 当您从metadata.getAsTree(..)而不是空结构时,您可能想要使用setFromTree(..)

PS:如果这不是问题,请在更新元数据的位置添加代码并写入图像。 🙂