5

我正在尝试通过 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)

如果是每通道 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)`
  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.

4

1 回答 1

8

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

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

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

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

编辑

您在评论中指的是 TIFF 6.0 规范的第一部分,称为Baseline TIFF

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

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

Tiled Images 也是 Baseline 规范的扩展,其中StripOffsets,StripByteCountsRowsPerStripfields 被替换为TileWidth, TileLengthTileOffsets因此TileByteCounts您可以通过使用 . 查看现有字段来区分平铺图像和剥离图像TIFFGetField()

于 2013-04-16T10:25:23.743 回答