2013-04-16 47 views
5

我试图通过C语言处理每通道RGBA TIFF图像的16位,我无法在规范中找到大量有关16位图像的信息。TIFF图像:16bits-RGBA图像像素是如何交错的?

在每个通道8位RGBA图像的情况下,我知道一个像素存储为uint32,并且可以通过将32位分组为4个组(R,G,B,A)8位。 然后处理每个通道RGBA图像8位时,我做以下(也参见封闭源代码here):

  1. 我存储图像数据作为UINT32标签(使用TIFFReadRGBAImageOriented),我打电话data_tiff
  2. 我去隔行像素使用以下命令:(uint8) TIFFGetR(*data_tiff)(uint8) TIFFGetG(*data_tiff)(uint8) TIFFGetB(*data_tiff) & (uint8) TIFFGetA(*data_tiff)

在每信道RGBA图像的16位的情况下,你能告诉我怎么我可以去隔行像素吗? 如果我能retreive图像数据作为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. 我使用(uint16) TIFF16GetR(*data_tiff)(uint16) TIFF16GetG(*data_tiff)读取图像数据作为UINT64标签
  2. 我去隔行像素,(uint16) TIFF16GetB(*data_tiff) & (uint16) TIFF16GetA(*data_tiff)

但似乎数据并非本地存储在uint64选项卡,所以我不知道如何隔行扫描16位每通道图像到一个uin t32像素选项卡。

处理16位,我也面临着困难灰度化(使用TIFFReadRGBAImageOriented得到的图像数据,并试图每个像素转换成UINT16)

更普遍地以同样的方式的图像,你有任何一块有关16位灰度和彩色图像的文档?

谢谢 最好的问候,

雷米A.

+1

你是什么意思的上面的单词“选项卡”?我无法解析......应该是“桌子”,也许吧? – unwind

+0

我的意思是一个指针:uint32 * –

回答

6

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

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

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

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

编辑

什么你是指在评论是被称为基线TIFF

«当引入TIFF的TIFF 6.0规范的第一部分,它的可扩展挑起兼容性 问题。编码的灵活性引发了一个笑话,TIFF 代表成千上万的不兼容文件格式。[9]为了避免这些问题,每个TIFF阅读器都需要阅读Baseline TIFF。 基线TIFF不包含图层,或者使用JPEG或 LZW进行压缩。基线TIFF的正式名称为TIFF 6.0,第1部分:基线 TIFF从Wikipedia

一个基线TIFF»不支持位深度高于8位,所以这就是为什么在基线TIFF的规格,对于灰度图像的值BitsPerSample只能是4或8,对于RGB图像,每个通道只能有8位。作为Baseline TIFF规范的扩展,支持更高的比特深度,并且不需要以支持TIFF阅读器,因此需要

平铺图像也是一个扩展基线规范,其中StripOffsetsStripByteCounts,和RowsPerStrip字段由TileWidthTileLengthTileOffsetsTileByteCounts代替,从而可以通过使用在现有字段寻找区分从剥离图像平铺图像TIFFGetField()

+0

谢谢你的回答,我可以读一些你在网上建议的东西,它也表示面向扫描线接口的主要限制,除了需要首先识别现有文件因为拥有合适的组织,只有当数据未以压缩格式存储时,或者图像数据条的行数设置为1(RowsPerStrip为1)时,才能随机访问各条扫描线。这意味着处理16位图像的这种方式对于任何16位图像都无效,您是否知道另一种方法来实现这一点? –

+0

是的,我编辑了我的答案,明确了扫描线方法的局限性。 – zakinster

+0

好的谢谢你这个非常完整的答案。 我会很乐意使用高级库,但我介绍的依赖性越少,它就越好...... –