[Utils] Exif 2.1 specification

Exif 标准是由JEIDA制定的,但目前网络上还没有公开的文档资料。此文档由TsuruZoh Tachibanaya无偿贡献。

什么是Exif文件格式

通常来说,Exif文件格式和JPEG文件格式是等价的。Exif基于JPEG标准向JPEG文件格式中插入了一些图片信息和产生图片的设备(相机、制图软件等)的信息。

JPEG格式和标识符

所有的JPEG图片都是以0xFF 0xD8作为文件开头,以0xFF 0xD9作为文件结尾。这些0xFF 0x??形式的字节内容,我们将其称为标识符,它标记了JPEG信息的数据段。其中0xFF为标识符前缀,后面跟随的0x??就是标识符定义了。
0xFF 0xD8被定义为SOI(Start of image),图片起始点。
0xFF 0xD9被定义为EOI(End of image),图片截止点。
0xFF 0xDB被定义为DQT(Quantization Table),量化表。
0xFF 0xC4被定义为DHT(Huffman Table),霍夫曼编码表。
0xFF 0xDD被定义为DRI(Restart Interval),图片内容定位点。
0xFF 0xC0被定义为SOF(Start of frame),帧头。
0xFF 0xDA被定义为SOS(Start of scan),扫描头。
这两个特殊的标识符后是不会跟随数据的,但其他的标识符后面都会跟随一段数据。

基本的数据段格式如下:
0xFF + 标识符定义(1个字节) + 数据段长度(2个字节) + 数据(n个字节)

  • 其中的“数据段长度”是个整型,字节序为大端序(Big endian)
  • 数据段的长度是包含了“数据段长度”所占用的2个字节的,所以真正的数据的长度 = 数据段长度 - 2
    如:0xFF 0xC1 0x00 0x0C
    标识符为0xFF 0xC1,其后跟随的数据段长度为0x00 0x0C(即12个字节),但真正去除了0xFF 0xC1 0x00 0x0C的数据只有10个字节

在JPEG文件格式中,SOI(图片起始:0xFF 0xD8)标记后,还可以定义很多个数据段,这些数据段的格式都如上所述,一个接着一个排列在SOI之后。所有的数据段结束后,跟随其后的就是SOS(Start of stream,数据流起始点)、图片数据和EOI(图片截止点)。

JPEG文件格式的基本组成如下:
SOI + 数据段1 + 数据段2 + …… + 数据段n + DQT + DHT + (DRI) + SOF + SOS + 图片数据 + EOI

JPEG的固定标识符

0xFF 0xE0~0xFF 0xEF的标识符都是JPEG定义的固定标识符,这个区段的标识符被称为“应用标识(APPn)”,它们定义了一系列用于存储不同种类信息的应用数据段,这些信息都是用户应用程序所需的一些图像、设备、自定义信息。n从0开始,到15截止,也就是说APP数据段一共有16个。
同时,它们也是JPEG格式中非必须的数据,也就是说,就算JPEG文件里没有它们,JPEG也一样能被正常显示和使用。

例如,老式的Olympus、Canon、Casio、Agfa数码相机使用JIFI(JPEG file interchange format)格式文件来存储拍摄的照片,而JIFI使用APP0(0xFF 0xE0)数据段来存储数码相机的配置信息和照片缩略图。

标识符 应用标识名 用途
0xFF 0xE0 APP0 存储JFIF文件格式的配置信息和图片缩略图
0xFF 0xE1 APP1 存储EXIF信息
0xFF 0xE2 APP2 -
0xFF 0xE3 APP3 -
0xFF 0xE4 APP4 -
0xFF 0xE5 APP5 -
0xFF 0xE6 APP6 -
0xFF 0xE7 APP7 -
0xFF 0xE8 APP8 -
0xFF 0xE9 APP9 -
0xFF 0xEA APP10 -
0xFF 0xEB APP11 -
0xFF 0xEC APP12 -
0xFF 0xED APP13 -
0xFF 0xEE APP14 -
0xFF 0xEF APP15 -

所以JPEG文件的格式定义可以认为是:
SOI + [APP0] + [APP1] + …… + [APP15] + SOS + 图片数据 + EOI

同样的,Exif格式也是使用APP数据段在JPEG格式文件中插入数据的。为了避免和JIFI冲突,Exif使用APP10xFF 0xE1)数据段来存储信息。

Exif格式定义

因为Exif是存储于一个JPEG的APP数据段中,所以Exif数据还是会包装在APP数据段格式中,如下:
SOI + [APP0] + [0xFF 0xE1 0x?? 0x?? + EXIF] + …… + [APPn] + SOS + 图片数据 + EOI

  • 其中0x?? 0x??为APP1数据段的长度

Exif的数据格式为TIFF格式,具体可参考Adobe公司编写的TIFF 6.0 标准文档。
在APP1数据段中包含的Exif信息主要有如下组成部分:

标识符 数据内容
0xFF 0xE0 APP1数据段标识
0x?? 0x?? APP1数据段长度(2字节大端序(BigEndian)表示)
0x45 0x78 0x69 0x66 0x00 0x00 Exif标识头(内容为ASCII码的"Exif\0\0")
0x49 0x49 0x2A 0x00 TIFF标识头(小端序版本)
0x4D 0x4D 0x00 0x2A TIFF标识头(大端序版本),TIFF标识头只会存在一个版本
0x?? 0x?? 0x?? 0x?? 下一个IFD的地址偏移量
0x?? ........ 0x?? IFD0(图片信息索引)的条目列表
0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 下一个IFD的地址偏移量
0x?? ........ 0x?? IFD0条目的数据存放区域
0x?? ........ 0x?? Exif的条目列表
0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 下一个IFD的地址偏移量
0x?? ........ 0x?? Exif条目的数据存放区域
0x?? ........ 0x?? IFD1(缩略图信息索引)的条目列表
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 下一个IFD的地址偏移量(为0则代表不再有IFD节点)
0x?? ........ 0x?? IFD1条目的数据存放区域
0xFF 0xD8 0x?? ........ 0x?? 0xFF 0xD9 缩略图JPEG内容

TIFF格式定义

TIFF标识头

虽然JPEG格式的内容只使用大端字节序来存储数据,但Exif所采用的TIFF格式则可以选择大端字节序(Big Endian)或小端字节序(Little Endian)来存储数据。

TIFF标识头的格式如下:
字节序标识(2个字节) + 字节序示例(2个字节) + 第一个IFD的地址偏移(4个字节)

  • 字节序标识:用于标记字节序
    • 0x49 0x49为ASCII码"II"的字符内容,它表示TIFF采用了以Intel为代表小端字节序
    • 0x4D 0x4D为ASCII码"MM"的字符内容,它表示TIFF采用了以Motorola为代表大端字节序
  • 字节序示例:用于展示整型42在不同字节序下的表示方式
    • 0x2A 0x00为小端序表示法
    • 0x00 0x2A为大端序表示法
  • 第一个IFD的地址偏移, 如果TIFF标识头之后紧跟第一个IFD,那么这里记录的偏移量就是8
    • 0x08 0x00 0x00 0x00为小端序整型8的表示
    • 0x00 0x00 0x00 0x08为大端序整型8的表示
IFD(Image file directory)图片信息索引

IFD图片信息索引的内容包含:
信息条目的数量(2个字节) + 条目1(2个字节) + ...... + 条目n(12个字节) + 下一个IFD的地址偏移(4个字节)

IFD的条目由包含下面4个部分:
条目标识(2个字节) + 数据类型(2个字节) + 数值精度(4个字节) + 数值或数值的相对地址(4个字节)

  • 条目标识用来标记这个条目的名称,条目名称对照表详见章节“TIFF标识”
  • 数据类型用来标记这个条目的数值的数据类型,TIFF定义了12种数据类型,数据类型对照表详见章节“TIFF标识”
  • 数值精度跟数据类型是对应的,不同数据类型有不同的数据精度,它表示一个数值占用的字节长度,从1个字节到8个字节不等,数值精度对照表详见章节“TIFF标识”
  • 当数据能被4个字节表示,则此处存放的为数值。如果数据的长度超过了4个字节,那么此处则存放一个相对地址,用于指示数据被存放在IFD条目的数据存放区域中的位置
IFD缩略图

缩略图一般放在APP1中的IFD1之后,缩略图可以有3种格式来存储:

TIFF标识

IFD标识
标识 IFD名称 数据类型 数据长度 描述
0x01 0x0E ImageDescription ascii string 图片描述
0x01 0x0F Make ascii string 拍摄图片的设备制造商
0x01 0x10 Model ascii string 拍摄图片的设备型号
0x01 0x12 Orientation unsigned short 1 图片朝向:详见下表
0x01 0x1A XResolution unsigned rational 1 横向分辨率,每单位长度上的像素点数量
0x01 0x1B YResolution unsigned rational 1 纵向分辨率,每单位长度上的像素点数量
0x01 0x28 ResolutionUnit unsigned short 1 分辨率单位,1为无单位,2为英寸,3为厘米
0x01 0x31 Software ascii string 拍摄图片的设备固件版本号
0x01 0x32 DateTime ascii string 20 图片拍摄日期:"YYYY:MM:DD HH:MM:SS\0"
0x01 0x3E WhitePoint unsigned rational 2 图片中高光的色温定义
0x01 0x3F PrimaryChromaticities unsigned rational 6 图片的色度均衡定义
0x02 0x11 YCbCrCoefficients unsigned rational 3 如果图片颜色空间为YCbCr,则它表示RGB转换到亮度时,RGB分量的比例关系,默认为“0.299/0.587/0.114”
0x02 0x13 YCbCrPositioning unsigned short 1 如果图片颜色空间为YCbCr且使用降采样时,则它表示子像素阵列的色度采样方式,1为中心点采样,2为基准点采样
0x02 0x14 ReferenceBlackWhite unsigned rational 6 图片中黑色和白色的参考值
0x82 0x98 Copyright ascii string 版本信息
0x87 0x69 ExifOffset unsigned long 1 到Exif IFD的地址偏移量
0x90 0x03 DateTimeOriginal ascii string 20 图片拍摄日期,同DateTime(0x01 0x32
朝向枚举值 旋转翻转(顺时针旋转)
1
2 0° + 水平翻转
3 180°
4 180° + 水平翻转
5 270° + 水平翻转
6 270°
7 90° + 水平翻转
8 90°
9 未定义
IFD数据类型
标识 数据类型 数值精度(每个数值占用的字节数) 备注
0x01 unsigned byte 1 -
0x02 ascii strings 1 -
0x03 unsigned short 2 -
0x04 unsigned long 4 -
0x05 unsigned rational 8 分数类型,前4个字节为分子,后4个字节为分母
0x06 signed byte 1 -
0x07 undefined 1 -
0x08 signed short 2 -
0x09 signed long 4 -
0x0A signed rational 8 分数类型,前4个字节为分子,后4个字节为分母
0x0B signed float 4 -
0x0C signed double 8 -

【未完....喂碗土豆儿后待续】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • JPEG格式和标志JPEG文件都是以十六进制的 0xFFD8 开始,以 0xFFD9 结束。在JPEG数据中,0x...
    cain_huang阅读 7,316评论 7 2
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,850评论 6 13
  • JPEG文件的存储格式有很多种,但最常用的是JFIF格式,即JPEG File Interchange Forma...
    hehtao阅读 8,925评论 1 7
  • 那天,你說要走, 問我,要不要留。 留下,許不了天長地久, 只好,狠下心默默點頭。 那天,你想要走, 問我,要不要...
    欢乐V英雄阅读 228评论 2 4
  • “人的气质本是天生的,早就有了定数,是难以轻易改变的,只有读书才能改变自己的气质。” 读《曾国藩家书——...
    好妈妈自带光芒阅读 584评论 7 0