我正在尝试将GPS数据添加到我在Java中创建的TIFF文件中。我正在使用JAI-ImageIO库,但如果有更好的库来完成GPS元数据和自定义元数据,我愿意考虑它。如何将GPS元数据添加到Java中的TIFF?
我试图直接将GPS元数据添加到节点,但它似乎剥离了GPS IDF标签。我试图将GPS IFD添加到TIFFIFD对象(来自TIFFIMageMetadata对象),但似乎没有正确保存数据。
基本上,我正在努力让它正确地保存GPS数据,并试图找出如何获取数据。在互联网上搜索的时间在教程和帮助中几乎没有变化,我没有看到任何有助于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对象可能会更好。
已更新,以添加额外的代码,以显示我如何创建图像以及如何保存它。
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类型) - 当我将它附加到根时,它似乎删除它来自元数据节点。
是'TIFF_METADATA_FORMAT'“com_sun_media_imageio_plugins_tiff_image_1.0”还是别的? – haraldK
它就是那个文本 - 我从getMetadataFormats()函数中复制了它。 – aperkins
嗯..似乎有一些元数据结构的问题。'TIFFIFD'标签被定义(在DTD中)具有属性“parentTagNumber”和“parentTagName”,而不是“数字”和“名称”。请注意,名称都是多余的,我会在代码中避免它们,以减少冗长。另外,我认为'gpsRootNode'应该是'ifd'的孩子(就像在代码中一样),而不是编辑中的'root'。这是一个次IFD,而不是第二个图像的IFD。 – haraldK