一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

标签图像文件格式(Tag Image File Format,TIFF)是一种灵活的位图格式,主要用来存储包括照片和艺术图在内的图像,最初由 Aldus 公司与微软公司一起为 PostScript 打印开发。TIFF 与 JPEG 和 PNG 一起成为流行的高位彩色图像格式。

TIFF文件以 .tif 或 .tiff 为扩展名。其数据格式是一种3级体系结构,TIFF 文件内部结构可以分成三个部分,分别是:文件头信息区(IFH)、图像文件目录(IFD)和图像数据区。其中所有的标签都是以升序排列,这些标签信息是用来处理文件中的图像信息的。

由于 TIFF 文件中使用的偏移量为 4 个字节,所以,tif 文件最大为 4GB,而新的 BigTIFF 文件格式是为打破此限制而设计的格式,此处不表。

图像文件头 IFH

图像头文件(Image File Header 简称 IFH),IFH 数据结构包含 3 个成员共计8个字节,如下所示:

OffsetDataTypeValue
0 Word Byte order indication
2 Word Version number (always 42)
4 Unsigned Long Offset to first IFD

详细解释:

  • Byte order indication:
    2 字节,位于文件最开始,其取值为 "MM"(0x4d4d) 或 "II"(0x4949),"MM" 表示大字节在先的字节顺序,"II" 表示小字节在先的字节顺序。

  • Version number:
    2 字节,其值永远为 "42"(0x002a),是“为了其深刻的哲学意义”而选择的。

  • Offset to first IFD:
    4 字节,第一个 IFD 相对于文件起始位置的偏移量(对于多页 TIFF 可以存在多个 IFD)

注意:

  • TIFF 文件中所使用的偏移量,都是相对于文件头位置的偏移量;
  • 偏移量必须以 Word 边界开始,也就是说,所有偏移量必须为偶数。

图像文件目录(IFD)

图像文件目录(Image File Directory)是 TIFF 图中非常重要的数据结构,一个 TIFF 文件可以包含多个 IFD,这时表示此文件包含多个图像,一个 IFD 标识一个图像的属性。

IFD 包含 3 类成员,如下所示:

OffsetDataTypeValue
0 Word Directory Entry Count
2 Word Directory Entry 0
14 Word Directory Entry 1
\vdots Word \vdots
2+(Count-1)*12 Word Directory Entry (count-1)
2+(Count)*12 Unsigned Long Offset to next IFD

详细解释:

  • Directory Entry Count:
    2字节,接下来的 DE(Directory Entry)的个数

  • Directory Entry:
    12字节,表示图像的某一个属性,共有 Directory Entry Count 个

  • Offset to next IFD:
    4字节,下一个 IFD 的偏移量,如果已经是最后一个IFD,则此值为 NULL(0x00000000)

Directory Entry

Directory Entry 简称 DE, 简单的说,一个 DE 记录一个图像的属性,例如图像的 长、宽、分辨率等。其存储结构如下所示:

OffsetDataTypeValue
0 Word Tag
2 Word Type
4 Unsigned Long Length
8 Unsigned Long value Offset

详细解释:

  • Tag:
    2 字节,该属性的标签编号,在 IFD 中,多个 DE 的 Tag 值是升序排列的,此编号可以在 TIFF 的规范中找到,此处列出几个常用的编号(用户也可以定义自己的私有标签):

    TagNameDecimalHexTypeValue
    ImageWidth 256 0x100 SHORT or LONG  
    ImageLength 257 0x101 SHORT or LONG  
    BitsPerSample 258 0x102 SHORT 4 or 8
    Compression 259 0x103 SHORT  
    PhotometricInterpretation 262 0x106 SHORT  
    StripOffsets 273 0x111 SHORT or LONG  
    RowsPerStrip 278 0x116 SHORT or LONG  
    StripByteCounts 279 0x117 LONG or SHORT  
    XResolution 282 0x11A RATIONAL  
    YResolution 283 0x11B RATIONAL  
    ResolutionUnit 296 0x128 SHORT  
  • Type:
    2 字节,该属性的数据的数据类型,该值可以在 TIFF 规范中找到,下面列出:

    ValueTypeDescription
    1 BYTE 8-bit unsigned integer.
    2 ASCII 8-bit byte that contains a 7-bit ASCII code; the last byte must be NUL (binary zero).
    3 SHORT 16-bit (2-byte) unsigned integer.
    4 LONG 32-bit (4-byte) unsigned integer.
    5 RATIONAL Two LONGs: the first represents the numerator of a fraction; the second, the denominator.
    6 SBYTE An 8-bit signed (twos-complement) integer.
    7 UNDEFINED An 8-bit byte that may contain anything, depending on the definition of the field.
    8 SSHORT A 16-bit (2-byte) signed (twos-complement) integer.
    9 SLONG A 32-bit (4-byte) signed (twos-complement) integer.
    10 SRATIONAL Two SLONG’s: the first represents the numerator of a fraction, the second the denominator.
    11 FLOAT Single precision (4-byte) IEEE format.
    12 DOUBLE Double precision (8-byte) IEEE format.
  • Length:
    4 字节,数据的数量,注意,此处为数据的数量而不是数据的字节数

  • valueOffset:
    4 字节,如果数据的数量乘以数据类型的字节长度(即实际数据的字节数)小于等于 4,则此处存储数据,否则,此处存储数据位置的偏移量(相对于文件头的偏移量)

其文件结构总览如下图所示:

 
TIFF文件格式总览.png

图像数据例子

TIFF 文件的 IFD 并不一定紧跟在 IFH 后面,相反,它常常位于图像数据的后面,即 TIFF 图像文件的一般组织形式是:
IFH -- 图像数据 -- IFD

下面我们制作一个 TIFF 格式的文件进行简单分析
用 画图 软件绘制一个 7*9 像素的图像,保存为 TIFF 格式

TIFF例子文件

放大截图显示为:

 
TIFF例子截图.png

其文件的实际内容为(16进制):

Offset0123456789abcdef
0000 0000 49 49 2a 00 ca 00 00 00 80 3e 14 2a 40 39 78 b6
0000 0010 00 84 26 61 41 f8 61 22 1d 08 00 3e 56 2b 37 f3
0000 0020 b9 de 04 16 0a cb 48 a4 40 92 3c 86 90 44 0c e4
0000 0030 c7 1b d1 ee 03 7d 82 0c c1 71 10 84 aa 4e 65 0f
0000 0040 47 c5 00 00 04 18 91 48 bf dd 4e a0 02 a1 50 a2
0000 0050 14 0a 00 cb 45 73 6a 6a 1d 84 3f 58 ec 77 fa d9
0000 0060 6c 20 71 80 9b 02 40 c8 3c f6 63 6a 42 1e d0 87
0000 0070 e1 9d 2e c2 01 bc c2 a0 10 1b f8 b0 5d 7d 09 c1
0000 0080 4d e0 a8 1c 03 08 01 cf 9f ec 87 3b 64 20 10 00
0000 0090 0f 49 2f 20 50 0c 0f 10 10 83 03 6a e5 73 fd aa
0000 00a0 ec 71 bd 5f 6f 91 c9 39 ca f7 7e be 42 00 60 66
0000 00b0 41 f3 0e 7f 87 03 8f f2 ea 15 9e fd 7f bf 5d cf
0000 00c0 a7 93 d5 f8 f7 7c bf 9f 70 10 0f 00 fe 00 04 00
0000 00d0 01 00 00 00 00 00 00 00 00 01 04 00 01 00 00 00
0000 00e0 07 00 00 00 01 01 04 00 01 00 00 00 09 00 00 00
0000 00f0 02 01 03 00 03 00 00 00 84 01 00 00 03 01 03 00
0000 0100 01 00 00 00 05 00 00 00 06 01 03 00 01 00 00 00
0000 0110 02 00 00 00 11 01 04 00 01 00 00 00 08 00 00 00
0000 0120 15 01 03 00 01 00 00 00 03 00 00 00 16 01 04 00
0000 0130 01 00 00 00 09 00 00 00 17 01 04 00 01 00 00 00
0000 0140 c2 00 00 00 1a 01 05 00 01 00 00 00 8a 01 00 00
0000 0150 1b 01 05 00 01 00 00 00 92 01 00 00 1c 01 03 00
0000 0160 01 00 00 00 01 00 00 00 28 01 03 00 01 00 00 00
0000 0170 02 00 00 00 3d 01 03 00 01 00 00 00 02 00 00 00
0000 0180 00 00 00 00 08 00 08 00 08 00 00 77 01 00 e8 03
0000 0190 00 00 00 77 01 00 e8 03 00 00            

对其进行简要解析(偏移量省略高位两个字节的0x0000):

  • 0x0000 ~ 0x0007
    IFH, 其中 最开始的两个字节内容 0x4949 为 "II", 表示此文件的字节顺序为小字节在先;接下来的两个个字节 0x2a 0x00 按照 Word 类型解析为 0x002a 为固定值 42,接下来的 4 个字节解析为 IFD 的偏移地址为:0x000000ca;

  • 0x00ca ~ 0x00cb
    IFD 的起始位置,开始的两个字节解析为 0x000f, 为 Directory Entry Count, 表示下面有 15 个 Directory Entry;

  • 0x00cc ~ 0x00d7
    Directory Entry 0, 开始两个字节为 Tag = 0x00fe, 表示 NewSubfileType, 具体可查看附件中的 TIFF 规范;

  • 0x00d8 ~ 0x00e3
    DE 1, 开始的 2 个字节 Tag = 0x0100, 表示 ImageWidth, 接下来的 2 个字节 Type = 0x0004 表示数据格式为 LONG(32bits), 再接下来的 4 个字节 Length = 0x00000001, 表示数据个数为 1, 再接下来的 4 个字节表示此 ImageWidth = 0x00000007, 表示图像宽度为 7;

  • 0x00e4 ~ 0x00ef
    DE 2, 开始的 2 个字节 Tag = 0x0101, 表示 ImageLength, 不再详述;

  • 0x00f0 ~ 0x00fb
    DE 3, 开始的 2 个字节 Tag = 0x0102, 表示 BitsPerSample, 为每个组件的位数;接下来的 2 个字节 Type = 0x0003, 表示数据格式为 SHORT, 接下来的 4 个字节 Length = 0x00000003, 表示数据个数为 3; 此处应当计算 3 (数据格式字节数)= 32=6, 即数据为 6 个字节,所以接下来的 4 个字节保存数据的偏移量位置 value Offset = 0x00000184;

    • 0x0184 ~ 0x0189
      此处存储 BitsPerSample 的数据,可以看到,其数据为 0x0008 0x0008 0x0008, 表示图像为3通道,每个通道的像素为 8 位深度;
  • 0x00fc ~ 0x0107
    DE 4, 开始的 2 个字节 Tag = 0x0103, 表示 Compression, 为压缩的属性,此处的值为 0x05, 表示数据是 LZW 压缩的;

  • 0x0108 ~ 0x0113
    DE 5, Tag = 0x0106, 表示 PhotometricInterpretation, 值为 2 表示为 RGB 图像;

  • 0x0114 ~ 0x011F
    DE 6, Tag = 0x0111, 表示 StripOffsets, For each strip, the byte offset of that strip. 此处 Type = 4, 表示 LONG 数据类型,Length = 0x00000001, 数据只有 1 个,其值为 0x00000008, 表示数据存放在偏移量 0x08 开始的数据处;

    • 0x0008~0x00c9
      此处存放的数据即为图像的像素数据,验证图像像素值,其并不等于文件中的数值,应该是经过压缩的原因;
  • 0x0120 ~ 0x012B
    DE 7, Tag = 0x0115, 表示 SamplesPerPixel, 每个像素的组件数,对于 RGB 图像此属性值为3; 查看此值确实为 3;

  • 0x012C ~ 0x0137
    DE 8, Tag = 0x0116, 表示 RowsPerStrip, The number of rows in each strip (except possibly the last strip.) 一个 Strip 中的行数,此处值为 9 (此处只有 1 个 strip, 此值为 9);

  • 0x0138 ~ 0x0143
    DE 9, Tag = 0x0117, 表示 StripByteCounts, For each strip, the number of bytes in the strip after compression. 字节数,此处值为 0xc2 = 194 字节;

  • 0x0144 ~ 0x014f
    DE 10, Tag = 0x011a, 表示 XResolution, The number of pixels per ResolutionUnit in the ImageWidth direction. Type = 0x05, 表示 RATIONAL 类型(分数类型,分子分母都为LONG),length = 0x00000001, 数据个数为 1 个;Value Offset = 0x0000018a;

    • 0x018a~0x0191
      X 方向分辨率值,分子为 0x017700 分母为 0x00003e8,所以值为:0x60=96;
  • 0x0150 ~ 0x015B
    DE 11, Tag = 0x011b, 表示 YResolution, Type = 0x05, length = 0x00000001, Value Offset = 0x00000192;

    • 0x0192~0x0199
      Y 方向分辨率值,分子为 0x0x017700 分母为 0x00003e8,所以值为:0x60=96;
  • 0x015C ~ 0x0167
    DE 12, Tag = 0x011c, 表示 PlanarConfiguration,How the components of each pixel are stored. 值为 1 ,表示 1 = Chunky format. The component values for each pixel are stored contiguously. The order of the components within the pixel is specified by PhotometricInterpretation. For example, for RGB data, the data is stored as RGBRGBRGB…;

  • 0x0168 ~ 0x0173
    DE 13, Tag = 0x0128, 表示 ResolutionUnit, 1 = No absolute unit of measurement. Used for images that may have a non-square aspect ratio but no meaningful absolute dimensions. 2 = Inch. 3 = Centimeter. Default = 2 (inch); 此处值为 2;

  • 0x0174 ~ 0x017f
    DE 14, Tag = 0x013d, 表示 Predictor, 此处值为 2, 此参数是与 LZW 压缩有关的参数;

  • 0x0180 ~ 0x0183
    Offset to next IFD, 由于本文件中只有一幅图像,所以只有一个 IFD, 所以此处的偏移量值为 NUL = 0x00000000;

 

posted on 2020-12-18 16:16  一杯清酒邀明月  阅读(977)  评论(0编辑  收藏  举报