原文链接
Fig.1. Basic Structure of JPEG Files.
JPEG SOI : FF D8 // 图片起始 JPEG APP1: FF E1 APP1 Size : 1C 45 // 注意:前面这三个WORD都是big endian的 EXIF Flag : 'Exif', 0, 0 --------- TIFF : TIFF Header: Byte Order: 'II' Flag : 2A 00 IFD0 offset : 08 00 00 00 ---------------------------- IFD0: Entries Count : 0B 00 // 11 DE 1: Tag : 0E 01 // Image Description 图像说明 Type : 02 00 // ASCII Size : 0B 00 00 00 Value : 92 00 00 00 // from TIFF Header DE 2: Tag : 0F 01 // Make 制造 Type : 02 00 Size : 06 00 00 00 Value: B2 00 00 00 DE 3: Tag : 10 01 // Model 型号 Type : 02 00 Size : 05 00 00 00 Value: CA 00 00 00 … DE 11: Tag : 69 87 // EXIF IFD Type : 04 00 // LONG Size : 01 00 00 00 Value: 1C 01 00 00 // Offset of EXIF IFD IFD1 Offset : 18 03 00 00 // END of IFD0 IFD0 DATA: ... // 存放IFD0中DE 的Value数据 EXIF sub IFD : Entries Count : 18 00 DE : Tag : 9A 82 // Exposure time ... Next IFD : 00 00 00 00 // END of EXIF IFD. 按标准IFD规定,表示没有后继IFD EXIF sub IFD Data : ... // 存放EXIF sub IFD的Value数据 ----------------------------------------------- IFD1 : // EXIF中用于存放缩略图 Entries Count : 06 00 DE : Tag : 03 01 ... Next IFD : 00 00 00 00 // END OF IFD1. EXIF只用到两个TIFF IFD IFD1 Data : ... // Thumbnail etc. ----------------------------------- // end of TIFF ----------------------------- // 其它JPEG Marker segments JPEG EOI : FF D9 // 图片结束 |
FFE1 | APP1 标记 | ||||
SSSS | APP1 数据 | APP1 数据大小 | |||
45786966 0000 | Exif 头 | ||||
49492A00 08000000 | TIFF 头 | ||||
XXXX. . . . | IFD0 (主图像) | 目录 | |||
LLLLLLLL | 连接到 IFD1 | ||||
XXXX. . . . | IFD0的数据域 | ||||
XXXX. . . . | | Exif 子IFD | 目录 | ||
00000000 | 连接结束 | ||||
XXXX. . . . | Exif 子IFD的数据域 | ||||
XXXX. . . . | | Interoperability IFD | Directory | ||
00000000 | 连接结束 | ||||
XXXX. . . . | Interoperability IFD的数据域 | ||||
XXXX. . . . | Makernote IFD | Directory | |||
00000000 | 连接结束 | ||||
XXXX. . . . | Makernote IFD的数据域 | ||||
XXXX. . . . | IFD1(缩略图像) | 目录 | |||
00000000 | 连接结束 | ||||
XXXX. . . . | IFD1的数据域 | ||||
FFD8XXXX. . . XXXXFFD9 | 缩略图像 |
TagID | 属性名称 | type | 说明 |
8769 | EXIF IFD | LONG | 数字相机的信息 |
8825 | GPS IFD | LONG | 地理位置信息 |
A005 | Interoperability IFD | LONG | 互操作扩展信息 |
927C | MakerNote IFD | LONG | 厂商自己独有的注释信息 |
一个EXIF的二进制表示:
0000: 49 49 2A 00 08 00 00 00-02 00 1A 01 05 00 01 00
0010: 00 00 26 00 00 00 69 87-04 00 01 00 00 00 11 02
0020: 00 00 40 00 00 00 48 00-00 00 01 00 00 00
· 前两个字节是 "I I", 所以字节序是 'Intel'.
· 在地址0x0004~0x0007处存放的值是 0x08000000, 因此IFD0 从地址 '0x0008'开始
· 在地址0x0008~0x0009处存放的值是 0x0200, 则表示IFD0有 '2' 个目录项.
· 在地址0x000a~0x000b处存放的值是 0x1A01, 它意味着这是一个 XResolution(0x011A) 标签, 表示这是图像的水平分辨率.
· 地址0x000c~0x000d处存放的值为 0x0500, 说明数据的格式是一个 unsigned rational(0x0005).
· 地址0x000e~0x0011处存放的值是 0x01000000, 说明组件的数据只有 '1'个. Unsigned rational的数据大小是8字节(组件的大小), 因此数据的总长度是 1x8=8字节.
· 总数居长度比4字节大了, 因此它后面的4个字节里面存放的是一个指向实际数据的偏移量地址.
· 地址0x0012~0x0015处存放的是 0x26000000, 表示XResolution(水平分辨率) 数据的存储地址是0x0026
· 地址0x0026~0x0029处存放的数据是 0x48000000, 说明分子的值为 72, 而地址0x002a~0x002d 处存放的是0x0100000000, 说明分母为 '1'. 因此XResoultion 的值是 72/1.
· 地址0x0016~0x0017处存放的数据为0x6987, 表示下一个标签是 ExifOffset(0x8769). 这就是 指向 Exif子IFD的偏移量
· 而它的数据格式是 0x0004, 即是一个无符号的长整形(unsigned long integer).
· 这个标签只有一个组件. 无符号长整形的数据大小是4字节, 因此总数据长度为4字节.
· 总数据长度是 4字节, 则说明下一个4字节的数据中存放的是Exif子IFD的偏移量.
· 地址0x001e~0x0021处存放的是 0x11020000, 则说明Exif子IFD的开始地址是 '0x0211'.
· 这是最后一个目录项, 接下来的4个字节存放的是下一个IFD的偏移地址.
· 地址0x0022~0x0025处存放的是 0x40000000, 就可以知道下一个IFD的开始地址为 '0x0040'
EXIF中的缩略图
JPEG格式的缩略图
TIFF格式的缩略图
EXIF Orientation | 翻转方式 |
1 | 未翻转 |
2* | 左右翻转 |
3 | 180度旋转 |
4* | 上下翻转 |
5* | 左旋转90度后上下翻转 |
6 | 右旋转90度 |
7* | 右旋转90度后上下翻转 |
8 | 左旋转90度 |
IFD0 ( 主图像 ) 使用的标签 | |||||||||||||||||||||||||||||||
标签号 | 标签名 | 格式 | 组件数 | 描述 | |||||||||||||||||||||||||||
0x010e | ImageDescription | ascii string | | 用来描述图像 . 双字节的字符码不能使用 , 如 中文 / 韩文 / 日文 . | |||||||||||||||||||||||||||
0x010f | Make | ascii string | | 表示数字相机的制造商 . 在 Exif 标准中 , 这个标签是可选的 , 但是在 DCF 中它是必需的 . | |||||||||||||||||||||||||||
0x0110 | Model | ascii string | | 表示数字相机的模块代码 . 在 Exif 标准中 , 这个标签是可选的 , 但在 DCF 中它也是必需的 . | |||||||||||||||||||||||||||
0x0112 | Orientation | unsigned short | 1 |
当拍照时 , 相机相对于场景的方向 . 在右边表示的是 '0th row' 以及 '0th column' 在视觉位置上的关系 . | |||||||||||||||||||||||||||
0x011a | XResolution | unsigned rational | 1 | 图像的 显示 / 打印 分辨率 . 缺省值是 1/72 英寸 , 但是它没有意义因为个人 PC 在 显示 / 打印 图像的时候不使用这个值 . | |||||||||||||||||||||||||||
0x011b | YResolution | unsigned rational | 1 | ||||||||||||||||||||||||||||
0x0128 | ResolutionUnit | unsigned short | 1 | XResolution(0x011a)/YResolution(0x011b) 的单位 . '1' 表示没有单位 , '2' 意味着英寸 , '3' 表示厘米 . 缺省值是 '2'( 英寸 ). | |||||||||||||||||||||||||||
0x0131 | Software | ascii string | | 显示固件的版本号 ( 数字相机的内部控制软件 ). | |||||||||||||||||||||||||||
0x0132 | DateTime | ascii string | 20 | 图像最后一次被修改时的日期 / 时间 . 日期的格式是 "YYYY:MM:DD HH:MM:SS"+0x00, 一共 20 个字节 . 如果没有设置时钟或者数字相机没有时钟 , 则这个域是用空格来填充 . 通常 , 它和 DateTimeOriginal(0x9003) 具有相同的值 | |||||||||||||||||||||||||||
0x013e | WhitePoint | unsigned rational | 2 | 定义图像白点 (white point/ 白点:在彩色分色、照相或摄影时作为色彩平衡测量用途的参考点 ) 的色度 (chromaticity). 如果图像是用 CIE 标准照度 D65( 著名的是 ' 光线 /daylight' 的国际标准 ), 这个值是 '3127/10000,3290/10000'. | |||||||||||||||||||||||||||
0 x013f | PrimaryChromaticities | unsigned rational | 6 | 定义图像的原始色度 . 如果图像使用 CCIR 推荐 709 原始色度 , 则这个值是 '640/1000,330/1000,300/1000,600/1000,150/1000,0/1000'. | |||||||||||||||||||||||||||
0x0211 | YCbCrCoefficients | unsigned rational | 3 | 当图像的格式是 YCbCr(JPEG 的格式 ), 这个值表示转换成 RGB 格式的一个常量 . 通常 , 这个值是 '0.299/0.587/0.114'. | |||||||||||||||||||||||||||
0x0213 | YCbCrPositioning | unsigned short | 1 | 当图像的格式是 YCbCr 并且使用 ' 子采样 /Subsampling'( 色度数据的剪切值 , 所有的数字相机都使用 ), 定义了 subsampling 像素阵列的色度采样点 . '1' 表示像素阵列的中心 , '2' 表示基准点 . | |||||||||||||||||||||||||||
0x0214 | ReferenceBlackWhite | unsigned rational | 6 | 表示黑点 (black point)/ 白点 的参考值 . 在 YCbCr 格式中 , 前两个值是 Y 的黑点 / 白点 , 下两个值是 Cb, 最后两个值是 Cr. 而在 RGB 格式中 , 前两个表示 R 的黑点 / 白点 , 下两个是 G, 最后两个是 B. | |||||||||||||||||||||||||||
0x8298 | Copyright | ascii string | | 表示版权信息 | |||||||||||||||||||||||||||
0x8769 | ExifOffset | unsigned long | 1 | Exif 子 IFD 的偏移量 |
Exif 子 IFD 使用的标签 | |||||||||||||||||||||||||||||||||||||||||||||||||||
标签号 | 标签名 | 格式 | 组件数 | 描述 | |||||||||||||||||||||||||||||||||||||||||||||||
0x829a | ExposureTime | unsigned rational | 1 | 曝光时间 ( 快门速度的倒数 ). 单位是秒 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x829d | FNumber | unsigned rational | 1 | 拍照时的光圈 F-number(F-stop). | |||||||||||||||||||||||||||||||||||||||||||||||
0x8822 | ExposureProgram | unsigned short | 1 | 拍照时相机使用的曝光程序 . '1' 表示手动曝光 , '2' 表示正常程序曝光 , '3' 表示光圈优先曝光 , '4' 表示快门优先曝光 , '5' 表示创意程序 ( 慢速程序 ), '6' 表示动作程序 ( 高速程序 ), '7' 表示 肖像模式 , '8' 表示风景模式 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x8827 | ISOSpeedRatings | unsigned short | 2 | CCD 的感光度 , 等效于 Ag-Hr 胶片的速率 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9000 | ExifVersion | undefined | 4 | Exif 的版本号 . 用 4 个 ASCII 字符来存储 . 如果图片是基于 Exif V2.1 的 , 这个值是 "0210". 因为它不是一个用 NULL(0x00) 来终结的字符串,所以这里的类型是 'undefined'. | |||||||||||||||||||||||||||||||||||||||||||||||
0x9003 | DateTimeOriginal | ascii string | 20 | 照片在被拍下来的日期 / 时间 . 使用用户的软件是不能被修改这个值的 . 日期的格式是 "YYYY:MM:DD HH:MM:SS"+0x00, 一共占用 20 个字节 . 如果数字相机没有设置时钟或者 数字相机没有时钟 , 这个域使用空格来填充 . 在 Exif 标准中 , 这个标签是可选的 , 但是在 DCF 中是必需的 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9004 | DateTimeDigitized | ascii string | 20 | 照片被数字化时的日期 / 时间 . 通常 , 它与 DateTimeOriginal(0x9003) 具有相同的值 . 数据格式是 "YYYY:MM:DD HH:MM:SS"+0x00, 一共占用 20 个字节 . 如果数字相机没有设置时钟或者 数字相机没有时钟 , 这个域使用空格来填充 . 在 Exif 标准中 , 这个标签是可选的 , 但是在 DCF 中是必需的 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9101 | ComponentsConfiguration | undefined | | 表示的是像素数据的顺序 . 大多数情况下 RGB 格式使用 '0x04,0x05,0x06,0x00' 而 YCbCr 格式使用 '0x01,0x02,0x03,0x00'. 0x00: 并不存在 , 其他的对应关系为 0x01:Y, 0x02:Cb, 0x03:Cr, 0x04:Red, 0x05:Green, 0x06:Bllue. | |||||||||||||||||||||||||||||||||||||||||||||||
0x9102 | CompressedBitsPerPixel | unsigned rational | 1 | JPEG ( 粗略的估计 ) 的平均压缩率 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9201 | ShutterSpeedValue | signed rational | 1 | 用 APEX 表示出的快门速度 . 为了转换成原始的 'Shutter Speed'; 则先要计算 2 的 ShutterSpeedValue 次幂 , 然后求倒数 . 例如 , 如果 ShutterSpeedValue 是 '4', 快门速度则是 1/(2 4 )=1/16 秒 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9202 | ApertureValue | unsigned rational | 1 | 拍照时镜头的光圈 . 单位是 APEX. 为了转换成普通的 F-number(F-stop), 则要先计算出根号 2 2 (=1.4142) 的 ApertureValue 次幂 . 例如 , 如果 ApertureValue 是 '5', F-number 就等于 1.4142 5 = F5.6. | |||||||||||||||||||||||||||||||||||||||||||||||
0x9203 | BrightnessValue | signed rational | 1 | 被拍摄对象的明度 , 单位是 APEX. 为了从 BrigtnessValue(Bv) 计算出曝光量 (Ev), 你必须加上 SensitivityValue(Sv). Ev=Bv+Sv Sv=log 2 (ISOSpeedRating/3.125) ISO100:Sv=5, ISO200:Sv=6, ISO400:Sv=7, ISO125:Sv=5.32. | |||||||||||||||||||||||||||||||||||||||||||||||
0x9204 | ExposureBiasValue | signed rational | 1 | 照片拍摄时的曝光补偿 . 单位是 APEX(EV). | |||||||||||||||||||||||||||||||||||||||||||||||
0x9205 | MaxApertureValue | unsigned rational | 1 | 镜头的最大光圈值 . 你可以通过计算根号 2 的 MaxApertureValue 次幂来转换成普通的光圈 F-number ( 跟 ApertureValue:0x9202 的处理过程一样 ). | |||||||||||||||||||||||||||||||||||||||||||||||
0x9206 | SubjectDistance | signed rational | 1 | 到焦点的距离 , 单位是米 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9207 | MeteringMode | unsigned short | 1 | 曝光的测光方法 . '0' 表示未知 , '1' 为平均测光 , '2' 为中央重点测光 , '3' 是点测光 , '4' 是多点测光 , '5' 是多区域测光 , '6' 部分测光 , '255' 则是其他 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9208 | LightSource | unsigned short | 1 | 光源 , 实际上是表示白平衡设置 . '0' 意味着未知 , '1' 是日光 , '2' 是荧光灯 , '3' 白炽灯 ( 钨丝 ), '10' 闪光灯 , '17' 标准光 A, '18' 标准光 B, '19' 标准光 C, '20' D55, '21' D65, '22' D75, '255' 为其他 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9209 | Flash | unsigned short | 1 | '0' 表示闪光灯没有闪光 , '1' 表示闪光灯闪光 , '5' 表示闪光但没有检测反射光 , '7' 表示闪光且检测了反射光 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x920a | FocalLength | unsigned rational | 1 | 拍摄照片时的镜头的焦距长度 . 单位是毫米 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x927c | MakerNote | undefined | | 制造商的内部数据 . 一些制造商如 Olympus/Nikon/Sanyo 等在这个区域中使用 IFD 格式的数据 . | |||||||||||||||||||||||||||||||||||||||||||||||
0x9286 | UserComment | undefined | | 存储用户的注释 . 这个标签允许使用两字节的德字符或者 unicode. 前 8 个字节描述的是字符集 . 'JIS' 是日文 ( 著名的有 Kanji). '0x41,0x53,0x43,0x49,0x49,0x00,0x00,0x00':ASCII '0x4a,0x49,0x53,0x00,0x00,0x00,0x00,0x00':JIS '0x55,0x4e,0x49,0x43,0x4f,0x44,0x45,0x00':Unicode '0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00':Undefined | |||||||||||||||||||||||||||||||||||||||||||||||
0x9290 | SubsecTime | ascii string | | 一些数字相机每秒能拍摄 2~30 张照片 , 但是 DateTime/DateTimeOriginal/DateTimeDigitized 标签只能记录到秒单位的时间 . SubsecTime 标签就是用来记录秒后面的数据 ( 微秒 ). 例如 , DateTimeOriginal = "1996:09:01 09:15:30", SubSecTimeOriginal = "130", 合并起来的原始的拍摄 时间就是 "1996:09:01 09:15:30.130" | |||||||||||||||||||||||||||||||||||||||||||||||
0x9291 | SubsecTimeOriginal | ascii string | | ||||||||||||||||||||||||||||||||||||||||||||||||
0x9292 | SubsecTimeDigitized | ascii string | | ||||||||||||||||||||||||||||||||||||||||||||||||
0xa000 | FlashPixVersion | undefined | 4 | 存储 FlashPix 的版本信息 . 如果图像数据是基于 FlashPix formar Ver.1.0, 则这个值为 "0100". 因为它不是一个用 NULL(0x00) 来终结的字符串,所以这里的类型是 'undefined'. | |||||||||||||||||||||||||||||||||||||||||||||||
0xa001 | ColorSpace | unsigned short | 1 | 定义色彩空间 . DCF 图像必须使用 sRGB 色彩空间因此这个值总是 '1'. 如果这个照片使用了 其他的色彩空间 , 这个值是 '65535': 未校准 (Uncalibrated). | |||||||||||||||||||||||||||||||||||||||||||||||
0xa002 | ExifImageWidth | unsigned short/long | 1 | 主图像的尺寸大小 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa003 | ExifImageHeight | unsigned short/long | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||
0xa004 | RelatedSoundFile | ascii string | | 如果数字相机能够纪录图像的音频数据 , 则表示音频数据的名字 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa005 | ExifInteroperabilityOffset | unsigned long | 1 | 表示这是一个扩展 "ExifR98", 细节未知 . 这个值经常是 IFD 格式的数据 . 当前这儿有两个 目录项 , 第一个是 Tag0x0001, 值是 "R98", 下一个是 Tag0x0002, 它的值为 "0100". | |||||||||||||||||||||||||||||||||||||||||||||||
0xa20e | FocalPlaneXResolution | unsigned rational | 1 | 表示 CCD 的像素密度 . 如果你的相机是百万像素的并且是用低分辨率 ( 如 VGA 模式 ) 来拍摄照片 , 这个值可以通过照片的分辨率来重新采样 . 在这种情况下 , FocalPlaneResolution 就不是 CCD 的实际的分辨率 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa20f | FocalPlaneYResolution | unsigned rational | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||
0xa210 | FocalPlaneResolutionUnit | unsigned short | 1 | FocalPlaneXResoluton/FocalPlaneYResolution 的单位 . '1' 表示没有单位 , '2' 是英寸 inch, '3' 表示厘米 . 注意 : 一些 Fujifilm 的数码相机 ( 如 .FX2700,FX2900,Finepix4700Z/40i 等 ) 使用的值是 '3' 所以它的单位一定是 ' 厘米 ' , 但是它们的分辨率单位就变成 '8.3mm?'(1/3in.?). 这是 Fuji 的 BUG? 从 Finepix4900Z 开始这个值就使用 '2' 了但仍然跟实际的值不吻合 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa215 | ExposureIndex | unsigned rational | 1 | 跟 ISOSpeedRatings(0x8827) 一样但是数据类型是 unsigned rational. 只有 Kodak 的数字相机使用 这个标签来替代 ISOSpeedRating, 我不知道这是为什么 ( 历史原因 ?). | |||||||||||||||||||||||||||||||||||||||||||||||
0xa217 | SensingMethod | unsigned short | 1 | 表示图像传感器单元的类型 . '2' 意味着这是一个芯片颜色区域传感器 , 几乎所有的数字相机都 使用这个类型 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa300 | FileSource | undefined | 1 | 显示图像来源 . 值 '0x03' 表示图像源是数字定格相机 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa301 | SceneType | undefined | 1 | 表示拍摄场景的类型 . 值 '0x01' 表示图像是通过相机直接拍摄出来的 . | |||||||||||||||||||||||||||||||||||||||||||||||
0xa302 | CFAPattern | undefined | | 表示色彩过滤阵列 (CFA) 几何模式 .
色彩过滤和 CFA 值之间的关系 .
例如 , 普通的 RGB 过滤器使用左表的副本 , 这个值是 '0x0002,0x0002,0x00,0x01,0x01,0x02'. |
Interoperability IFD 使用的标签 | ||||
标签号 | 标签名 | 格式 | 组件号 | 描述 |
0x0001 | InteroperabilityIndex | Ascii string | 4 | 如果这个 IFD 是主图像的 IFD 并且文件内容采用的是 ExifR98 v1.0, 那这个值就是 "R98". 如果是所略图的 , 这个值则是 "THM". |
0x0002 | InteroperabilityVersion | Undefined | 4 | 纪录 interoperability 的版本 . "0100" 表示版本 1.00. |
0x1000 | RelatedImageFileFormat | Ascii string | any | 纪录图像文件的文件格式 . 这个值是 ascii 字符串 ( 如 . "Exif JPEG Ver. 2.1"). |
0x1001 | RelatedImageWidth | Short or Long | 1 | 纪录图像的大小尺寸 . |
0x1001 | RelatedImageLength | Short or Long | 1 |