3

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

4

1 回答 1

1

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

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

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

于 2013-10-15T09:07:07.117 回答