TIFF图像:16bits-RGBA图像像素是如何隔行扫描的?

时间:2013-04-16 10:02:21

标签: c image libtiff

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

在每通道8位RGBA图像的情况下,我理解像素存储为uint32,并且可以通过将32位分组为8位的4组(R,G,B,A)来进行去交错。 。 然后为了处理每通道8位RGBA图像,我正在执行以下操作(另请参阅随附的源代码here):

  1. 我将图像数据存储为uint32标签(使用TIFFReadRGBAImageOriented),我称之为data_tiff
  2. 我使用以下命令对像素进行去隔行扫描:(uint8) TIFFGetR(*data_tiff)(uint8) TIFFGetG(*data_tiff)(uint8) TIFFGetB(*data_tiff)& (uint8) TIFFGetA(*data_tiff)
  3. 如果每通道RGBA图像为16位,您能告诉我如何对像素进行去隔行扫描? 如果我可以将图像数据作为uint64选项卡进行检索,那么我可以执行以下操作:

    #define    TIFF16GetR(abgr)    ((abgr) & 0xffff)
    #define    TIFF16GetG(abgr)    (((abgr) >> 16) & 0xffff)
    #define    TIFF16GetB(abgr)    (((abgr) >> 32) & 0xffff)
    #define    TIFF16GetA(abgr)    (((abgr) >> 48) & 0xffff)`
    
    1. 我将图像数据作为uint64标签
    2. 阅读
    3. 我使用(uint16) TIFF16GetR(*data_tiff)(uint16) TIFF16GetG(*data_tiff)(uint16) TIFF16GetB(*data_tiff)&去隔行像素。 (uint16) TIFF16GetA(*data_tiff)
    4. 但似乎数据本身并未存储在uint64选项卡中,所以我想知道如何将每个通道的16位图像隔行扫描到uint32像素选项卡中。

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

      更一般地说,你有关于16位灰度和彩色图像的任何文档吗?

      谢谢你, 最诚挚的问候,

      RémyA。

1 个答案:

答案 0 :(得分:7)

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

为了在不失去精度的情况下读取每通道16位图像,您可以直接使用TIFFReadScanline并根据SamplesPerPixelBitsPerSample读取正确的数据量。但这只有在图像存储在条带中时才有效(不是在TIFF 6.0中引入的图块),并且每个压缩条带中必须只有一行(如果图像被压缩)。

如果您想使用TIFFReadRGBAImage处理所有种TIFF图像,则必须检测图像格式并使用低级接口,例如TIFFReadEncodedStrip和{ {1}}。

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

修改

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

  

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

基线TIFF不支持高于8位的位深度,这就是为什么在基线TIFF的规范中,灰度图像的TIFFReadEncodedTile值只能是4或8,对于RGB图像in每个通道只能是8位。支持更高的位深度作为Baseline TIFF规范的扩展,并且TIFF阅读器支持它们不是 required

平铺图片也是基线规范的扩展,其中BitsPerSampleStripOffsetsStripByteCounts字段被RowsPerStripTileWidth,{{替换1}}和TileLength这样您就可以通过使用TileOffsets查看现有字段来区分平铺图像和剥离图像。