jpeg Exif file format  Marker APP1 简介

3 篇文章 0 订阅

jpeg Exif file format Marker APP1 简介

jpeg Exif file format Marker APP1 分析

 

参考: Description of Exif file format

 

Exif 文件格式与 JPEG 文件格式相同。 Exif 按照JPEG规范将图片的相关信息数据和缩略图图像插入JPEG。 因此可以使用 Internet 浏览器/图片浏览器/照片修饰软件等查看Exif格式的图像文件。

  • 图片的相关信息: 制造商、日期、曝光时间、焦距、光圈值等信息。

 

 

JPEG 的数据流如下:

 

Exif 数据结构:

Exif(APP1)基本结构如下面的表格所示:

TIFF Header:

TiFF header 指的是 TIFF 格式的前 8 个字节,前两个定义了 TIFF 数据采用何种字节顺序:

  • 如果是 0x4949 = II,表示采用 Inter 的小端字节顺序(49 49:01001001 01001001);
  • 如果为 0x4d4d = MM,表示采用 Motorola 的大端字节顺序(4d 4d:01001101 01001101);

例如:十进制值 305419896 的十六进制表示是:12345678,如果以 Motroal 式的 big-endian 进行存储,对应的 code unit 就是 0x12 0x34 0x56 0x78;而如果是 Intel 式的 little-endian 进行存储,则对应 0x78 0x56 0x34 0x12

 

IFD : Image file directory

以上表格中:

  • TTTT(2 个字节)表示的是 Tag number,表示一种类型的数据;
  • ffff(2 个字节)表示数据的格式;
  • NNNNNNNN 4byte :表示所组成元素的数量,实际长度 = 元素个数 x 数据格式, 如 unsigned long 占 4 byte (4N)
  • DDDDDDDD 4byte :表示所包含数据的长度,或者是数据存储地址的偏移量。如果总数据长度小于4字节,则“DDDDDDDD”存储该标记的值。如果其大小超过4字节,'DDDDDDDD'存储数据存储地址的偏移量。偏移的基准是 TIFF header (0x0C)

 

 

数据格式

 

IFD data structure

在 Exif 格式中,第一个图像文件目录(IFD)是 IFD0(主图像的 IFD),之后是 IFD1(缩略图的 IFD),接着图像文件目录链(IFD link)结束。IFD0/IFD1 中没有快门速度(shutter speed),焦距(focal length)等任何关于数码相机的信息。IFD0 有一个特别的标签(Tag)Exif Offset(0x8769),在这个标签中是 Exif SubIFD 的偏移量。Exif SubIFD 的数据格式也是 IFD 的数据格式,它包含了数码相机的相关信息。

 

IFD 标签

详细信息参阅:Description of Exif file format

libexif是一个用于解析,编辑和保存EXIF数据的库 https://github.com/libexif/libexif    libexif API

下面用 C 语言结构体描述 IFD 便签的信息。

// uint16_t app1_length[2]; // short , 数据长度
typedef struct IFD
{
    uint16_t tagNO;  // 标签编号
    uint16_t format; // 数据格式
    uint32_t length; // 数据长度
    uint32_t offset; // 数据偏移量,基地址 0x0C (Byte align)
    char tagName[50];   // 标签名
} IFD_S;



static const IFD_S IFD0[] =
{
    {0x010e, 2, 32, 0x0C, "ImageDescription"}, // 图片信息
    {0x010f, 2, 32, 0x0C, "Make"}, //相机制造商信息
    {0x0110, 2, 32, 0x0C, "Model"},  //相机模组信息
    {0x0112, 3, 2, 0x0C, "Orientation"}, // 方向
    {0x011a, 5, 8, 0x0C, "XResolution"}, // X分辨率
    {0x011b, 5, 8, 0x0C, "YResolution"}, // Y分辨率
    {0x0128, 3, 2, 0x0C, "ResolutionUnit"}, // 分辨率单位,  1'表示无单位,'2'表示英寸,'3'表示厘米
    {0x0131, 2, 32, 0x0C, "Software"}, // 软件
    {0x0132, 2, 20, 0x0C, "DateTime"}, // 日期
    {0x013e, 5, 8 * 2, 0x0C, "WhitePoint"}, // 照度
    {0x013f, 5, 8 * 6, 0x0C, "PrimaryChromaticities"},  // 色度
    {0x0211, 5, 8 * 3, 0x0C, "YCbCrCoefficients"}, // YCbCrCoefficients 颜色空间转换矩阵系数
    {0x0213, 3, 2, 0x0C, "YCbCrPositioning"}, // YCbCrPositioning 色相定位,色相配置
    {0x0214, 5, 8 * 5, 0x0C, "ReferenceBlackWhite"}, // ReferenceBlackWhite 黑白参照值
    {0x8298, 2, 32, 0x0C, "Copyright"}, // 版权
    {0x8769, 4, 4, 0x0C, "ExifOffset"}, // Offset to Exif Sub IFD
};



static const IFD_S subIFD[] =
{
    {0x829a, 5, 8, 0x0C, "ExposureTime"}, // 曝光时间
    {0x829d, 5, 8, 0x0C, "FNumber"}, // 光圈值
    {0x8822, 3, 2, 0x0C, "ExposureProgram"}, // 曝光模式
    {0x8827, 3, 2 * 2, 0x0C, "ISOSpeedRatings"}, // 感光度
    {0x9000, 7, 1 * 4, 0x0C, "ExifVersion"}, // Exif 版本
    {0x9003, 2, 20, 0x0C, "DateTimeOriginal"}, // 拍摄日期
    {0x9004, 2, 20, 0x0C, "DateTimeDigitized"}, // 数字日期
    {0x9101, 7, 1 * 4, 0x0C, "ComponentConfiguration"}, // ComponentConfiguration
    {0x9102, 5, 8, 0x0C, "CompressedBitsPerPixel"}, // 压缩时每像素色彩位
    {0x9201, 10, 8, 0x0C, "ShutterSpeedValue"}, // 快门速度
    {0x9202, 5, 8, 0x0C, "ApertureValue"}, // 光圈值
    {0x9203, 10, 8, 0x0C, "BrightnessValue"}, // 亮度值
    {0x9204, 10, 8, 0x0C, "ExposureBiasValue"}, // 曝光补偿
    {0x9205, 5, 8, 0x0C, "MaxApertureValue"}, // 最大光圈
    {0x9206, 10, 8, 0x0C, "SubjectDistance"}, // 物距
    {0x9207, 3, 2, 0x0C, "MeteringMode"}, // 曝光模式
    {0x9208, 3, 2, 0x0C, "LightSource"}, // 光源
    {0x9209, 3, 2, 0x0C, "Flash"}, // 闪光灯
    {0x920a, 5, 8, 0x0C, "FocalLength"}, // 焦距
    {0x927c, 7, 1, 0x0C, "MakerNote"}, // 制造商注释
    {0x9286, 7, 1, 0x0C, "UserComment"}, // 自定义注释
    {0xa000, 7, 1 * 4, 0x0C, "FlashPixVersion"}, // FlashPix版本
    {0xa001, 3, 2, 0x0C, "ColorSpace"}, // 色彩空间
    {0xa002, 3, 2, 0x0C, "ExifImageWidth"}, // Exif 图像宽度
    {0xa003, 3, 2, 0x0C, "ExifImageHeight"}, // Exif 图像高度
    {0xa004, 2, 32, 0x0C, "RelatedSoundFile"}, // 关联的声音文件
    {0xa005, 4, 4, 0x0C, "ExifInteroperabilityOffset"}, // 焦距平面X轴解析度
    {0xa20e, 5, 8, 0x0C, "FocalPlaneXResolution"}, // 焦距平面Y轴解析度
    {0xa20f, 5, 8, 0x0C, "FocalPlaneYResolution"}, // 焦距平面解析度单位
    {0xa210, 3, 2, 0x0C, "FocalPlaneResolutionUnit"}, // 焦距平面解析度单位
    {0xa217, 3, 2, 0x0C, "SensingMethod"}, // 显示图像传感器单元的类型
    {0xa300, 7, 1, 0x0C, "FileSource"}, // 源文件
    {0xa301, 7, 1, 0x0C, "SceneType"}, // 场景类型
};

static const IFD_S IFD1[] =
{
    {0x0100, 3, 2, 0x0C, "ImageWidth"}, // 图像宽度
    {0x0101, 3, 2, 0x0C, "ImageLength"}, // 图像高度
    {0x0102, 3, 2 * 3, 0x0C, "BitsPerSample"}, // 比特采样率/每个像素点位数
    {0x0103, 3, 2, 0x0C, "Compression"}, // 压缩比
    {0x0106, 3, 2, 0x0C, "PhotometricInterpretation"}, // 像素合成
    {0x0111, 3, 2, 0x0C, "StripOffsets"},  // 长度不定, 图像资料位置,条的偏移量
    {0x0115, 3, 2, 0x0C, "SamplesPerPixel"}, // 像素数
    {0x0116, 3, 2, 0x0C, "RowsPerStrip"}, // Strip 行数
    {0x0117, 3, 2, 0x0C, "StripByteConunts"},  // 长度不定 , Strip 字节数
    {0x011a, 5, 8, 0x0C, "XResolution"}, // X 水平分辨率
    {0x011b, 5, 8, 0x0C, "YResolution"}, // Y 水平分辨率
    {0x011c, 3, 2, 0x0C, "PlanarConfiguration"}, // 平面配置
    {0x0128, 3, 2, 0x0C, "ResolutionUnit"}, // 解析度,分辨率单位
    {0x0201, 4, 4, 0x0C, "JpegIFOffset"}, // JPEG 偏移量
    {0x0202, 4, 4, 0x0C, "JpegIFByteCount"}, // JPEG 图像数据大小
    {0x0211, 5, 8 * 3, 0x0C, "YCbCrCoefficients"}, // 颜色空间转换矩阵系数
    {0x0212, 3, 2 * 2, 0x0C, "YCbCrSubSampling"}, // 色相抽样比率
    {0x0213, 3, 2, 0x0C, "YCbCrPositioning"}, // 色相定位,色相配置
    {0x0214, 5, 8 * 6, 0x0C, "ReferenceBlackWhite"}, //  黑白参照值
 };

static const IFD_S miscTags[] =
{
    {0x00fe, 4, 4, 0x0C, "NewSubfileType"}, // 新的子文件类型
    {0x00ff, 3, 2, 0x0C, "SubfileType"}, // 子文件类型
    {0x012d, 3, 2 * 3, 0x0C, "TransferFunction"}, // 传输函数
    {0x013b, 2, 32, 0x0C, "Artist"}, // 艺术家
    {0x013d, 3, 2, 0x0C, "Predictor"}, // 预测器
    {0x0142, 3, 2, 0x0C, "TileWidth"}, // Tile 宽度
    {0x0143, 3, 2, 0x0C, "TileLength"}, // Tile 高度
    {0x0144, 4, 4, 0x0C, "TileOffsets"},  // 长度不定, Tile 偏移量
    {0x0145, 3, 2, 0x0C, "TileByteCounts"}, // 长度不定, Tile 字节数
    {0x014a, 4, 4, 0x0C, "SubIFDs"},  // 长度不定,
    {0x015b, 7, 1, 0x0C, "JPEGTables"}, // 长度不定,JPEG 表格/附录
    {0x828d, 3, 2 * 2, 0x0C, "CFARepeatPatternDim"}, //
    {0x828e, 1, 1, 0x0C, "CFAPattern"}, //
    {0x828f, 3, 2, 0x0C, "BatteryLevel"}, // 电池电量
    {0x83bb, 5, 8, 0x0C, "IPTC//NAA"},  // 长度不定
    {0x8773, 7, 1, 0x0C, "InterColorProfile"},   // 长度不定
    {0x8824, 2, 32, 0x0C, "SpectralSensitivity"}, // 光谱灵敏度,光谱感光度
    {0x8825, 4, 4, 0x0C, "GPSInfo"}, //
    {0x8828, 7, 1, 0x0C, "OECF"},   // 长度不定
    {0x8829, 3, 2, 0x0C, "Interlace"}, // Interlace 交错
    {0x882a, 3, 2, 0x0C, "TimeZoneOffset"}, // 时区偏移量
    {0x882b, 3, 2, 0x0C, "SelfTimerMode"}, // 自拍模式
    {0x920b, 5, 8, 0x0C, "FlashEnergy"}, // 闪光灯强度
    {0x920c, 7, 1, 0x0C, "SpatialFrequencyResponse"}, // 长度不定, 空间频率反应
    {0x920d, 7, 1, 0x0C, "Noise"},  // 长度不定, 噪声
    {0x9211, 4, 4, 0x0C, "ImageNumber"}, // 图像编号
    {0x9212, 2, 1, 0x0C, "SecurityClassification"}, // 安全等级
    {0x9213, 2, 32, 0x0C, "ImageHistory"}, //
    {0x9214, 3, 2 * 4, 0x0C, "SubjectLocation"}, // 物体位置
    {0x9215, 5, 8, 0x0C, "ExposureIndex"}, // 曝光指数
    {0x9216, 1, 1 * 4, 0x0C, "TIFF//EPStandardID"}, //
    {0x9290, 2, 32, 0x0C, "SubSecTime"}, //
    {0x9291, 2, 32, 0x0C, "SubSecTimeOriginal"}, //
    {0x9292, 2, 32, 0x0C, "SubSecTimeDigitized"}, //
    {0xa20b, 5, 8, 0x0C, "FlashEnergy"}, // 闪光灯强度
    {0xa20c, 3, 2, 0x0C, "SpatialFrequencyResponse"}, // 空间频率反应
    {0xa214, 3, 2, 0x0C, "SubjectLocation"}, // 物体位置
    {0xa215, 5, 8, 0x0C, "ExposureIndex"}, // 曝光指数
    {0xa302, 7, 1, 0x0C, "CFAPattern"}, //
};

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值