【问题标题】:Get TIFF tag value (including non-ASCII characters) from TIFF images in Java 11从 Java 11 中的 TIFF 图像中获取 TIFF 标签值(包括非 ASCII 字符)
【发布时间】:2020-10-26 12:53:30
【问题描述】:

我正在尝试从 Java 中的 TIFF 图像中读取不同的标签值(如标签 259(压缩)、33432(版权)、306(日期时间)、315(艺术家)等)。谁能建议在 Java 11 中获取这些值的最佳方法是什么?

我尝试使用 tiffinfo 命令(如“tiffinfo -c myfile.tif”)获取这些值。但我没有在 tiffinfo (libtiff) 或任何 Java 库中找到任何特定命令,这些命令将为我提供 TIFF 图像的特定标记值(例如 DateTime)。

更新:

正如 haraldK 建议的那样,我尝试了 ImageIO,如下所示

try (ImageInputStream input = ImageIO.createImageInputStream(tiffFile)) {
    ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle reader not found

    reader.setInput(input);
    IIOMetadata metadata = reader.getImageMetadata(0); 

    TIFFDirectory ifd = TIFFDirectory.createFromMetadata​(metadata);
    TIFFField dateTime = ifd.get​TIFFField(306); 
    String dateString = dateTime.getAsString(0);  
}

但它没有给出标签的确切值。如果是非 ASCII 值(ö、ü、ä 等),问号会替换实际值。

谁能告诉我如何从 TIFFField 获取标签的准确值(包括非 ASCII)?

【问题讨论】:

    标签: utf-8 tiff java-11 non-ascii-characters


    【解决方案1】:

    您可以使用标准 ImageIO,读取 TIFF 图像元数据并从中获取请求的值,例如通过在 JDK 中使用一些额外的支持类,从 Java 9 开始:

    try (ImageInputStream input = ImageIO.createImageInputStream(tiffFile)) {
        ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle reader not found
    
        reader.setInput(input);
        IIOMetadata metadata = reader.getImageMetadata(0); // 0 is the index of first image
    
        TIFFDirectory ifd = TIFFDirectory.createFromMetadata​(metadata);
        TIFFField dateTime = ifd.get​TIFFField(306); // Yes, that's 3 F's...
        String dateString = dateTime.getAsString(0); // TIFF dates are strings...
    }
    

    tiffFile 必须是有效的(现有的、可读的)java.io.File、java.io.RandomAccessFile 或 java.io.InputStream(或其他受支持的输入,这实际上是基于插件的)。如果不是,input 将是null,代码将失败。


    您可以使用类似但更详细的版本,只要您有 TIFF 插件,它就可以在旧版本的 Java 中工作:

    try (ImageInputStream input = ImageIO.createImageInputStream(tiffFile)) {
        ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle reader not found
    
        reader.setInput(input);
        IIOMetadata metadata = reader.getImageMetadata(0); // 0 is the index of first image
        // Get "native" TIFF metadata for first IFD
        IIOMetadataNode root = metadata.getAsTree("com_sun_media_imageio_plugins_tiff_image_1.0");
        Node ifd = root.getFirstChild();
        NodeList fields = ifd.getElementsByTagName("TIFFField"); // Yes, that's 3 F's...
        
        for (int i = 0; i < fields.getLength(); i++) {
            Element field = (Element) fields.item(i);
    
            if ("306".equals(field.getAttribute("number"))) {
                // This is your DateTime (306) tag, 
                // now do something with it ?
                // ...
            }
         }
    }
    

    虽然代码不太优雅...Java 9+ 的方法更简洁,也更容易推理。

    【讨论】:

    • 感谢您的回答。对于 TIFFField,javax.imageio.plugins.tiff.TIFFField;应该进口。正确的 ?但它仍然显示错误:无法解析符号'TIFField'。你知道这里有什么问题吗?
    • 是的。对不起,这是一个错字。这是TIFFField (3 Fs...)。固定。
    • tiffFile 的值为 /home/IdeaProjects/myfile/mytiff.tif。为什么它得到空值?
    • tiffFile 必须是有效的(现有且可读的)java.io.File 或 InputStream。但我假设你知道你的文件在哪里,它与上面的代码无关。 ?
    • 文件位置正确。我已经处理过图像。当我调试时,代码的执行在 ImageReader reader = ImageIO.getImageReaders(input).next(); 处停止
    猜你喜欢
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-04
    相关资源
    最近更新 更多