我正在尝试通过C语言处理每通道16位RGBA TIFF图像,我在规范中找不到关于16位图像的大量信息。
在每通道8位RGBA图像的情况下,我理解像素存储为uint32,并且可以通过将32位分组为8位的4组(R,G,B,A)来进行去交错。 。 然后为了处理每通道8位RGBA图像,我正在执行以下操作(另请参阅随附的源代码here):
data_tiff
(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)`
(uint16) TIFF16GetR(*data_tiff)
,(uint16) TIFF16GetG(*data_tiff)
,(uint16) TIFF16GetB(*data_tiff)
&去隔行像素。 (uint16) TIFF16GetA(*data_tiff)
但似乎数据本身并未存储在uint64选项卡中,所以我想知道如何将每个通道的16位图像隔行扫描到uint32像素选项卡中。
我也面临以同样方式处理16位灰度图像的困难(使用TIFFReadRGBAImageOriented
获取图像数据并尝试将每个像素转换为uint16)
更一般地说,你有关于16位灰度和彩色图像的任何文档吗?
谢谢你, 最诚挚的问候,
RémyA。
答案 0 :(得分:7)
TIFFReadRGBAImage
高级接口将始终以每个样本8位的精度读取图像。
为了在不失去精度的情况下读取每通道16位图像,您可以直接使用TIFFReadScanline
并根据SamplesPerPixel
和BitsPerSample
读取正确的数据量。但这只有在图像存储在条带中时才有效(不是在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 。
平铺图片也是基线规范的扩展,其中BitsPerSample
,StripOffsets
和StripByteCounts
字段被RowsPerStrip
,TileWidth
,{{替换1}}和TileLength
这样您就可以通过使用TileOffsets
查看现有字段来区分平铺图像和剥离图像。