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

Rém*_*gel 5 c image libtiff

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

在每通道8位RGBA图像的情况下,我理解像素存储为uint32,并且可以通过将32位分组为8位的4组(R,G,B,A)来进行解交织.然后为了处理每通道8位RGBA图像,我正在做以下事情(另请参见此处附带的源代码):

  1. 我将图像数据存储为我调用的uint32选项卡(使用TIFFReadRGBAImageOriented) data_tiff
  2. 我使用下列命令去隔行像素:(uint8) TIFFGetR(*data_tiff),(uint8) TIFFGetG(*data_tiff),(uint8) TIFFGetB(*data_tiff)(uint8) TIFFGetA(*data_tiff)

如果每通道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)`
Run Code Online (Sandbox Code Playgroud)
  1. 我将图像数据作为uint64选项卡读取
  2. 我使用隔行像素(uint16) TIFF16GetR(*data_tiff),(uint16) TIFF16GetG(*data_tiff),(uint16) TIFF16GetB(*data_tiff)(uint16) TIFF16GetA(*data_tiff)

但似乎数据本身并未存储在uint64选项卡中,所以我想知道如何将每通道16位的图像隔行扫描到uint32像素选项卡中.

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

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

谢谢您最好的问候,

雷米A.

zak*_*ter 7

TIFFReadRGBAImage高级接口将始终与每样本的8位的精度读出的图像.

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

如果你想要处理所有类型的TIFF图像,TIFFReadRGBAImage那么你必须检测图像格式并使用低级接口,如 TIFFReadEncodedStripTIFFReadEncodedTile.

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

编辑

你在评论中提到的是TIFF 6.0规范的第一部分,即Baseline 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阅读器支持他们.

平铺图像也是一个扩展基线规范,其中StripOffsets,StripByteCountsRowsPerStrip域所取代TileWidth,TileLength,TileOffsetsTileByteCounts这样你就可以考虑使用现有的领域区分一个精简图像的平铺图像TIFFGetField().