【问题标题】:LibTIFF: Extract all tags from a TIFF imageLibTIFF:从 TIFF 图像中提取所有标签
【发布时间】:2009-12-15 02:21:27
【问题描述】:

我目前正在从事一个项目,该项目需要我将 TIFF 图像拆分为一个包含所有标签的文件和一个包含所有图像数据的文件,并从这些文件中重建一个 TIFF 图像。唯一的问题是 LibTIFF 似乎没有提供从图像中​​获取所有标签的简单方法。我尝试使用 TIFFGetTagListCount 然后 TIFFGetField 来检索标签,但这只会返回标签的一小部分。我已经开始推出自己的版本,但我只是想仔细检查并确保我没有忽略某些东西,因为这似乎是一个非常明显的功能,应该包含在库中。

【问题讨论】:

  • 出于好奇,您找到解决此问题的方法了吗?

标签: c++ c tiff libtiff


【解决方案1】:

这是扫描所有标签可以获得的关闭:

 #include "LibTIFF/tif_dir.h"
 ...

 TIFFDirectory *td = &tif->tif_dir;

 for (int fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
    const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];

    // test if tag value is set
    // (lifted directly form LibTiff _TIFFWriteDirectory)

        if( fip->field_bit == FIELD_CUSTOM ) {
            int ci, is_set = FALSE;

            for( ci = 0; ci < td->td_customValueCount; ci++ )
                is_set |= (td->td_customValues[ci].info == fip);

            if( !is_set )
                continue;
        } else if(!TIFFFieldSet(tif, fip->field_bit))
            continue;

        // else: process the fip->field_tag


    }

请注意,您必须考虑到某些标签会出现两次(LONG 和 SHORT 版本),但其中只有一个有价值。可以在包含的标头(TIFFDirectory 结构)中查找要使用的正确类型。

还有其他关于如何阅读标签的问题,但这至少会让你遍历所有标签(标准标签)。如果遇到困难,请参阅 tif_dirinfo.c 获取指针。

【讨论】:

  • 好吧,既然tif_dir.h 是一个内部头文件(即不被构建的库公开),包括它会导致各种问题,如重新定义、缺少依赖项等。还有其他方法吗?
  • @Anish Ramaswamy 我不知道。如前所述,这是从 LibTIFF 源逆向工程的。如果您在重新定义时遇到问题,请尝试将其隔离在单独的翻译单元或小型库中。至于缺少decl。 - 其他包含也必须添加。 IIRC,只有头文件可以,不需要从 lib 编译任何 .c。
  • 这似乎不太优雅。我还在追捕中。谢谢!
【解决方案2】:

tifffile打印所有标签:

from tifffile import TiffFile
for page in TiffFile(path_to_file).pages:
    for tag in page.tags.values():
        print(tag.name, tag.code, tag.dtype, tag.count, tag.value)

【讨论】:

  • 另外,tifffile.py 似乎不支持 LZW 压缩的 tiff 文件
  • @matth 它确实支持它们(甚至早在 2018 年 10 月就支持了),但前提是满足对 imagecodecs 的可选依赖。
【解决方案3】:

addingtags.html in the libtiff documentation 包含有关处理非标准标签的信息(默认情况下它们被忽略)。会不会是这个问题?

【讨论】:

  • 非标准标签实际上不是问题,因为像 TIFF_IMAGEWIDTH 和 TIFF_IMAGELENGTH 这样的简单标准标签似乎不包含在标签列表计数中。其实很奇怪。
【解决方案4】:

您可以使用图像的tif_dir 字段。它是一个至少包含以下字段的结构:

  • td_customValueCount 包含“自定义”标签计数的数量,
  • td_customValuestd_customValueCount 标签值的列表(从 0 开始索引),类型为 TIFFTagValue *

所以你应该能够做这样的事情(以真正的在线代码方式,这是未经测试的,当然!):

for (i=0; i < tiffimage->tif_dir->td_customValueCount; ++i) {
    const TIFFFieldInfo *info = tiffimage->tif_dir->td_customValues[i].info;
    const char *tagname = info->field_name();
    /* process tag */
}

TIFFDirectory Struct Reference。希望对您有所帮助。

【讨论】:

    【解决方案5】:

    tiffdump 实用程序(与 libtiff 一起提供)实现了这一点,但查看代码,看起来它们主要是在库周围工作。他们实际上调用lseekread 来读取标签信息。

    【讨论】:

      【解决方案6】:

      【讨论】:

        【解决方案7】:

        纠正上面 cgohlke 回答中的 for 循环问题。还使用更完整的脚本进行扩展,因此更容易从命令行运行。

        import sys, getopt
        from tifffile import TiffFile
        
        def PrintAll(path_to_file):
            print('Tag.Name, Tag.Code, Tag.DType, Tag.Count, Tag.Value')
            for page in TiffFile(path_to_file).pages:
                for tag in page.tags.values():
                    print(tag.name, tag.code, tag.dtype, tag.count, tag.value)
        
        def main(argv):
            try:
                opts, args = getopt.getopt(argv, 'hi:v', ["help","image="])
            except getopt.GetoptError:
                print('Argv error')
                sys.exit(2)
            for opt, arg in opts:
                if opt in ('-h', '--help'):
                    print('printalltifftags.py -i c:\images\myimage.tif')
                    sys.exit(0)
                elif opt in ('-i', '--image'):
                    filePath = arg
            print('Image: ' + filePath)
            PrintAll(filePath)
        
        if __name__ == '__main__':
            main(sys.argv[1:])
        

        【讨论】:

          猜你喜欢
          • 2022-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多