如何在Java中将GPS元数据添加到TIFF? [英] How to add GPS metadata to TIFF in Java?

查看:161
本文介绍了如何在Java中将GPS元数据添加到TIFF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to add GPS data to a TIFF file I am creating in Java. I am using the JAI-ImageIO libraries, although if there is a better library for doing both GPS metadata and custom metadata, I am willing to look into it.

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

I have attempted to add the GPS metadata to the nodes directly, but it seems to strip off the GPS IDF tag. I have attempted to add the GPS IFD to the TIFFIFD object (from the TIFFIMageMetadata object), but that doesn't seem to save the data properly.

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

Basically, I am struggling to get it to save the GPS data properly, and trying to figure out how to get the data in there. Hours of searching on the internet have yielded little in the way of tutorials or help, and I don't see anything helpful on Stack Overflow, but my search abilities may be lacking.

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

Some code from my attempt at doing it by manipulating the metadata nodes directly:

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对象可能更好。

I am attempting to join the GPS root node in, along with a (currently hardcoded) value for the direction. Am I attaching at the wrong level, in the wrong place, in the wrong way, etc? I am fine doing it this way - although using the TIFF objects might be nicer.

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

Updated to add additional code, to show how I am creating the image, as well as how I am saving it.

ETA:

这个在这里:

ifd.appendChild(gpsRootNode);

实际应该是:

root.appendChild(gpsRootNode);

这是我尝试过的,但是当我将ifd节点作为我添加的节点时GPS节点,我得到一个例外:

This was something I was trying out, but when I do the ifd node as the node where I add the GPS node, I get an exception:

Exception in thread "Thread-2" java.lang.ClassCastException: com.sun.media.imageioimpl.plugins.tiff.TIFFIFD cannot be cast to [J

不确定是否是预期 - 看起来它正在尝试将IFD节点转换为Long数组(根据标准的JNI类型) - 当我将它附加到根时,它似乎只是从元数据节点中删除它。

Not sure if that is expected there - it looks like it is trying to cast the IFD node to a Long array (as per the standard JNI types) - when I attach it to the root, it just seems to remove it from the metadata nodes.

推荐答案

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

The problem is most likely that the metadata tree representation you are manipulating, is only a working copy. When you later write an image and pass it metadata, your changes to the tree representation are lost.

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

After you are done updating the metadata tree (root) with your GPS specific tags, you have to either call metadata.setFromTree(TIFF_METADATA_FORMAT, root) or metadata.mergeTree(TIFF_METADATA_FORMAT, root) to set/merge your changes back to the metadata instance. As you start out with metadata.getAsTree(..) rather than an empty structure, you probably want to use setFromTree(..).

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

PS: If this is not the problem, please add the code where you update your metadata and write the image. :-)

这篇关于如何在Java中将GPS元数据添加到TIFF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆