C TIFF图像:如何交错16位RGBA图像像素?

C TIFF图像:如何交错16位RGBA图像像素?,c,image,libtiff,C,Image,Libtiff,我试图通过C语言处理每通道16位的RGBA TIFF图像,我在规范中找不到很多关于16位图像的信息 对于每个通道8位的RGBA图像,我知道像素存储为uint32,并且可以通过将32位分组为8位的4组(R、G、B、a)来解交错。 然后,为了处理每个通道8位的RGBA图像,我将执行以下操作(另请参见随附的源代码): 我将图像数据存储为uint32选项卡(使用TIFFReadRGBAImageOriented),我称之为data\u tiff 我使用以下命令来解交错像素:(uint8)TIFFGetR

我试图通过C语言处理每通道16位的RGBA TIFF图像,我在规范中找不到很多关于16位图像的信息

对于每个通道8位的RGBA图像,我知道像素存储为uint32,并且可以通过将32位分组为8位的4组(R、G、B、a)来解交错。 然后,为了处理每个通道8位的RGBA图像,我将执行以下操作(另请参见随附的源代码):

  • 我将图像数据存储为uint32选项卡(使用TIFFReadRGBAImageOriented),我称之为
    data\u tiff
  • 我使用以下命令来解交错像素:
    (uint8)TIFFGetR(*data\u tiff)
    (uint8)TIFFGetG(*data\u tiff)
    (uint8)TIFFGetB(*data\u tiff)
    (uint8)TIFFGetA(*data\u tiff)
  • 如果是每通道16位的RGBA图像,您能告诉我如何逐行扫描像素吗? 如果可以将图像数据作为uint64选项卡检索,则可以执行以下操作:

    #define    TIFF16GetR(abgr)    ((abgr) & 0xffff)
    #define    TIFF16GetG(abgr)    (((abgr) >> 16) & 0xffff)
    #define    TIFF16GetB(abgr)    (((abgr) >> 32) & 0xffff)
    #define    TIFF16GetA(abgr)    (((abgr) >> 48) & 0xffff)`
    
  • 我将图像数据作为uint64选项卡读取
  • 我使用
    (uint16)TIFF16GetR(*data\u tiff)
    (uint16)TIFF16GetG(*data\u tiff)
    (uint16)TIFF16GetB(*data\u tiff)
    (uint16)TIFF16GetA(*data\u tiff)
  • 但数据似乎不是以本机方式存储在uint64选项卡中,因此我想知道如何将每通道16位的图像隔行扫描到uint32像素选项卡中

    我还面临着以同样的方式处理16位灰度图像的困难(使用
    TIFFReadRGBAImageOriented
    获取图像数据,并尝试将每个像素转换为uint16)

    一般来说,你有关于16位灰度和彩色图像的文档吗

    谢谢,, 致以最良好的祝愿


    Rémy A.

    TIFFReadRGBAImage高级界面将始终以每个样本8位的精度读取图像

    为了在不降低精度的情况下读取每通道16位图像,您可以直接使用
    TIFFReadScanline
    ,并根据
    SamplesPerPixel
    BitsPerSample
    读取正确数量的数据。但这仅适用于图像以条带形式存储(而不是TIFF 6.0中引入的平铺),并且每个压缩条带中必须只有一行(如果图像被压缩)

    如果要在不使用
    TIFFReadRGBAImage
    的情况下处理所有类型的TIFF图像,则必须检测图像格式并使用低级接口,如
    TIFFReadEncodedStrip
    TIFFReadEncodedTile

    请注意,TIFF规范非常广泛和灵活,使用这些低级接口来处理各种可能的图像并不是一件容易的事情,因此如果可以的话,您最好使用比libtiff更高级的库

    编辑

    您在评论中提到的是TIFF 6.0规范的第一部分,即基线TIFF

    «引入TIFF时,其可扩展性引发了兼容性 问题。编码的灵活性引发了一个笑话,TIFF 代表数千种不兼容的文件格式。[9]以避免这些问题 问题,每个TIFF阅读器都需要读取基准TIFF。这个 基线TIFF不包括图层,也不包括使用JPEG或 LZW。基准TIFF正式称为TIFF 6.0,第1部分:基准 TIFF»来自

    基线TIFF不支持高于8位的位深度,因此,在基线TIFF的规范中,灰度图像的
    BitsPerSample
    值只能为4或8,而RGB图像的每个通道只能为8位。作为基线TIFF规范的扩展,支持更高的位深度,TIFF阅读器不需要支持它们


    平铺图像也是基线规范的扩展,其中
    stripOffset
    StripByteCounts
    RowsPerStrip
    字段替换为
    TileWidth
    TileLength
    tileOffset
    TileByteCounts
    因此,通过使用
    TIFFGetField()

    查看现有字段,您可以区分平铺图像和剥离图像,上面的“选项卡”是什么意思?我无法解析那个。。。可能是“表格”吗?我指的是指针:uint32*谢谢你的回答,我可以在网上的某个地方读到一些你建议的东西,上面还说,面向扫描线的界面的主要限制,除了需要首先确定一个现有文件是否有合适的组织,仅当数据未以压缩格式存储时,或当图像数据条中的行数设置为1(RowsPerStrip为1)时,才能提供对单个扫描线的随机访问。这意味着这样一种处理16位图像的方法对任何16位图像都不起作用,你知道另一种方法吗?是的,我编辑了我的答案,明确了扫描线方法的局限性。好的,谢谢你给出了这个非常完整的答案。我很乐意使用高级库,但我介绍的依赖项越少越好……我已经阅读了更多关于您建议的内容,我还有几个问题:1。我如何知道图像是以条带还是平铺的形式存储(我看不到专门用于此问题的字段)2。您知道为什么TIFF Spec 6.0的第22页规定,在灰度图像的情况下,BitsPerSample字段的值应该是4或8(而不是16、32……)?3.对于RGB图像,同样的问题是,第24页写的BitsPerSample字段值应该是(8,8,8)再次感谢。我明白了,非常感谢:)事实上,处理所有类型的TIFF图像并不是一件容易的事情,我想我要将我的代码限制为灰度&RGB(A)图像,每个样本8、16和32位,这对大多数用户来说应该足够了。下一步将处理TIFF float。任何