通过Exiv2读取照片的Exif信息获取GPS,焦距等信息

  • A+
所属分类:系统文档

这里简单介绍一下如何通过开源C++工具包Exiv2读取图片中的属性信息

其实做这项工作之前也想偷懒百度一下的,大都是Java写的安卓 ExifInterface 类,这和我的工作扯不上一点关系啊,最后终于谷歌出了Exiv2开源C++库

一、简介

        ExifExchangeable image file format)即可交换图像文件格式是专门数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。

Exif最初由日本电子工业发展协会在1996年制定,版本为1.0。1998年,升级到2.1,增加了对音频文件的支持。2002年3月,发表了2.2版。

Exif可以附加于JPEGTIFFRIFF等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。

Windows 7操作系统具备对Exif的原生支持,通过鼠标右键点击图片打开菜单,点击属性并切换到详细信息标签下即可直接查看Exif信息。

Exif信息是可以被任意编辑的,因此只有参考的功能。

下表列出几项Exif会提供的消息,只是部分

项目 信息(举例)
制造厂商 Canon
相机型号 Canon EOS-1Ds Mark III
图象方向 正常(upper-left)
图象分辨率X 300
图象分辨率Y 300
分辨率单位 dpi
Software Adobe Photoshop CS Macintosh
最后异动时间 2005:10:06 12:53:19
YCbCrPositioning 2
曝光时间 0.00800 (1/125) sec
光圈 F22
拍摄模式 光圈优先
ISO感光值 100
Exif信息版本 30,32,32,31
图象拍摄时间 2005:09:25 15:00:18
图象存入时间 2005:09:25 15:00:18
曝光补偿(EV+-) 0
测光模式 点测光(Spot)
闪光灯 关闭
镜头实体焦长 12 mm
Flashpix版本 30,31,30,30
图象色域空间 sRGB
图象尺寸X 5616 pixel
图象尺寸Y 3744 pixel

二、Exif信息解析(摘自http://blog.csdn.net/fioletfly/article/details/53605959

实例分析:PICT0021.JPG

00   FF D8 FF E1 3A 59 45 78 69 66 00 00 4D 4D 00 2A 
10   00 00 00 08 00 0C 01 0E 00 02 00 00 00 0E 00 00
20   03 F4 01 0F 00 02 00 00 00 20 00 00 04 02 01 10
30   00 02 00 00 00 20 00 00 04 22 01 12 00 03 00 00
40   00 01 00 01 00 00 01 1A 00 05 00 00 00 01 00 00
50   04 42 01 1B 00 05 00 00 00 01 00 00 04 4A 01 28
60   00 03 00 00 00 01 00 02 00 00 01 31 00 02 00 00 
70   00 20 00 00 04 52 01 32 00 02 00 00 00 14 00 00
80   04 72 02 13 00 03 00 00 00 01 00 01 00 00 87 69
90   00 04 00 00 00 01 00 00 00 9E 88 25 00 04 00 00
A0   00 01 00 00 02 A2 00 00 02 E4 00 28 82 9A 00 05
B0   00 00 00 01 00 00 04 86 82 9D 00 05 00 00 00 01
C0   00 00 04 8E 88 22 00 03 00 00 00 01 00 02 00 00
D0   88 27 00 03 00 00 00 01 00 C8 00 00 90 00 00 07
E0   00 00 00 04 30 32 32 31 90 03 00 02 00 00 00 14
F0   00 00 04 96 90 04 00 02 00 00 00 14 00 00 04 AA
100  91 01 00 07 00 00 00 04 01 02 03 00 91 02 00 05
110  00 00 00 01 00 00 04 BE 92 01 00 0A 00 00 00 01
120  00 00 04 C6 92 02 00 05 00 00 00 01 00 00 04 CE
130  92 04 00 0A 00 00 00 01 00 00 04 D6 92 05 00 05
140  00 00 00 01 00 00 04 DE 92 06 00 05 00 00 00 01
150  00 00 04 E6 92 07 00 03 00 00 00 01 00 02 00 00
160  92 08 00 03 00 00 00 01 00 00 00 00 92 09 00 03
170  00 00 00 01 00 20 00 00 92 0A 00 05 00 00 00 01
180  00 00 04 EE 92 7C 00 07 00 00 00 40 00 00 04 F6
190  A0 00 00 07 00 00 00 04 30 31 30 30 A0 01 00 03
1A0  00 00 00 01 00 01 00 00 A0 02 00 04 00 00 00 01
1B0  00 00 12 00 A0 03 00 04 00 00 00 01 00 00 0D 80
1C0  A0 05 00 04 00 00 00 01 00 00 02 84 A2 15 00 05
1D0  00 00 00 01 00 00 05 36 A2 17 00 03 00 00 00 01
1E0  00 02 00 00 A3 00 00 07 00 00 00 01 03 00 00 00
1F0  A3 01 00 07 00 00 00 01 01 00 00 00 A4 01 00 03
200  00 00 00 01 00 00 00 00 A4 02 00 03 00 00 00 01
210  00 00 00 00 A4 03 00 03 00 00 00 01 00 00 00 00
220  A4 04 00 05 00 00 00 01 00 00 05 3E A4 05 00 03
230  00 00 00 01 00 29 00 00 A4 06 00 03 00 00 00 01
240  00 00 00 00 A4 07 00 03 00 00 00 01 00 00 00 00
250  A4 08 00 03 00 00 00 01 00 00 00 00 A4 09 00 03
260  00 00 00 01 00 00 00 00 A4 0A 00 03 00 00 00 01
270  00 00 00 00 A4 0B 00 07 00 00 00 04 00 00 00 00
280  A4 0C 00 03 00 00 00 01 00 00 00 00 00 00 00 00
290  00 02 00 01 00 02 00 00 00 04 52 39 38 00 00 02
2A0  00 07 00 00 00 04 30 31 30 30 00 00 00 00 00 05
2B0  00 00 00 01 00 00 00 04 02 02 00 00 00 01 00 02
2C0  00 00 00 02 4E 00 00 00 00 02 00 05 00 00 00 03
2D0  00 00 05 46 00 03 00 02 00 00 00 02 45 00 00 00
2E0  00 04 00 05 00 00 00 03 00 00 05 5E 00 00 00 00
2F0  00 06 01 03 00 03 00 00 00 01 00 06 00 00 01 1A
300  00 05 00 00 00 01 00 00 05 76 01 1B 00 05 00 00
310  00 01 00 00 05 7E 01 28 00 03 00 00 00 01 00 02
320  00 00 02 01 00 04 00 00 00 01 00 00 07 F4 02 02
330  00 04 00 00 00 01 00 00 32 5D 00 00 00 00 00 00
   
   FF D8       SOI
   FF E1       APP1
   3A 59       APP1 LENGTH
   45 78 69 66 00 00 Exif ASCII结束符两个
   4D 4D       MM big endian TIFF Header (注意小端的为:49492A00 08000000)
   00 2A       fixed
   00 00 00 08 IFD0 offset
   00 0C       IFD0: number of TAGs 12个tag,每个12字节。
   01 0E       TAG      Image title   
   00 02       TYPE ASCII
   00 00 00 0E count   最多13个字符
   00 00 03 F4 offset +0C=0x400 可以看到DCIM\100MEDIA (0x0c from the start of the TIFF header 4D4D MM)

   01 0F       TAG Image input equipment manuf 
   00 02       TYPE ASCII
   00 00 00 20 count   最多31个字符
   00 00 04 02 offset +0c=0x040E 可以看到TCL

   01 10       TAG Image input equipment model 
   00 02       TYPE ASCII
   00 00 00 20 count
   00 00 04 22 offset +0c=0x042E 可以看到SDV05
   
   01 12       TAG Orientation of image 
   00 03       SHORT             00 01
   00 00 00 01 count
   00 01 00 00 value 
   
   01 1A       TAG Image resolution in width 0x0442+0c=0x44E,可以看到00 00 00 48/00 00 00 01
   00 05       RATIONAL 
   00 00 00 01 count
   00 00 04 42 offset +0c=0x44E,可以看到00 00 00 48/00 00 00 01
   
   01 1B       TAG Image resolution in height 
   00 05       RATIONAL
   00 00 00 01 
   00 00 04 4A offset+0c=0x456 可以看到00 00 00 48/00 00 00 01
   
   01 28       Unit of X and Y resolution
   00 03       SHORT                00 02
   00 00 00 01 
   00 02 00 00 
   
   01 31       Software used 
   00 02       ASCII
   00 00 00 20 count
   00 00 04 52 offset +0c =0x45E 可以看到0.0.2
   
   01 32       DateTime 
   00 02       ASCII
   00 00 00 14 20字节
   00 00 04 72 offset+0c=0x47E,可以看到2012:07:29 21:28:18
   
   02 13       YCbCrPositioning
   00 03       SHORT      00 01
   00 00 00 01 
   00 01 00 00
   
   87 69       Exif IFD Pointer
   00 04       LONG
   00 00 00 01 count
   00 00 00 9E offset+0c=0xAA
   
   88 25       GPS Info IFD Pointer
   00 04       LONG
   00 00 00 01 count
   00 00 02 A2 offset+0c=0x02AE
   
   00 00 02 E4 nextIFD IFD1 offset
   
   00 28  Exif IFD number of TAGs
   82 9A  ExposureTime
   00 05  RATIONAL
   00 00 00 01 count
   00 00 04 86 offset+0c=0x0492
   ...

   Exif的相关信息这里先不做分析,请大家参照上面的文档自己分析了。

   

   这里主要是分析GPS相关信息

   GPS Info IFD Pointer 0x02AE  从上面数据2A0行的后面看数据
   00 05       count of TAGs
   
   00 00       GPSVersionID
   00 01       BYTE
   00 00 00 04 count
   02 02 00 00 value 2.2.0.0
   
   00 01       GPSLatitudeRef
   00 02       ASCII
   00 00 00 02 count
   4E 00 00 00 N North  
   
   00 02       GPSLatitude
   00 05       RATIONAL                 前4字节为分子,后4字节为分母,十六进制先转为十进制
   00 00 00 03 count
   00 00 05 46 offset+0c=0x552   16 00 00 00 01 00 00 00 22 00 00 00 01 00 00 00 51 00 00 00 04 00 00 00
                                                       22/1=22                             34/1=34                              81/4= 20.25
                                                      通过windows的右键属性看详细信息:22;34;20.249999999999915
   00 03       GPSLongitudeRef
   00 02
   00 00 00 02 count

   45 00 00 00 East
   
   00 04       GPSLongitude
   00 05       RATIONAL
   00 00 00 03 count
   00 00 05 5E offset+0c=0x56A     71 00 00 00 01 00 00 00 37 00 00 00 01 00 00 00 6C 00 00 00 04 00
                                                       113/1=113                          55/1=55                             108/4=27
                                                    通过windows的右键属性看详细信息:113;55;27.000000000000171

550 04 00 16 00 00 00 01 00 00 00 22 00 00 00 01 00 
560 00 00 51 00 00 00 04 00 00 00 71 00 00 00 01 00
570 00 00 37 00 00 00 01 00 00 00 6C 00 00 00 04 00
580 00 00 00 00 00 48 00 00 00 01 00 00 00 48 00 00
590 00 01 00 00 00 00 00 00


上面的分析知识帮助理解Exif文件在图片中的存储协议,加深印象,这个在我的实际操作中并未使用(因为我也不晓得作者是怎么把图片解码成这样的)

三、应用Exiv2工具包(下载地址

刚开始我实在Windows7+VS2013环境下使用的,但是在添加路径读取图片的时候始终不能成功,现在想来应该是动态链接库等各种配置没有搞定,后来就老老实实的切到了ubuntu+Qt下,修改了一下examples,终于成功了(也算能给老师交差了)

在ubuntu下,文件包的结构是这样的
dist/linux/bin/exiv2                                   exiv2 and sample applications
dist/linux/lib/libexiv2.so.26.0.0                   shared library
dist/linux/include/exiv2/                             include files
dist/linux/share/                                          man pages
dist/samples/                                           sample code
dist/logs/                                               log files
dist/contrib/Qt                                         Qt code and notes

要运行exiv2库,在终端下执行

$ cd dist$ export LD_LIBRARY_PATH="$PWD/linux/lib:$LD_LIBRARY_PATH"$ linux/bin/exiv2To compile and link your own code:$ cd dist$ sudo cp -R linux/* /usr/local/$ g++ -std=c++98 samples/exifprint.cpp -L/usr/local/lib -lexiv2 -o exifprint$ ./exifprint --versionexiv2=0.26.0...xmlns=xmpidq:http://ns.adobe.com/xmp/Identifier/qual/1.0/$

显示如上就算是完成安装完成了,然后新建一个控制台工程,把刚才的共享库等包含在工程的配置文件中,参考examples或者下载的解压包中的samples文件夹中的例程,修修改改,基本上就满足我的需求了

在Exiv2库中,可以读写的属性信息参考此链接

效果图,以GPS信息为例,这是windows7下右键属性读到的信息

通过Exiv2读取照片的Exif信息获取GPS,焦距等信息

这是利用Exiv2读到的

通过Exiv2读取照片的Exif信息获取GPS,焦距等信息

filepath--想要读取的图片的路径

exifDataName--此链接中的Key值

代码方法1

std::string getValueOfTag1(std::string filepath, std::string &exifDataName){Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filepath);if(image.get() == 0)cout<<"failed to opened..."<<endl;image->readMetadata();Exiv2::ExifData &exifData = image->exifData();if (exifData.empty()) {std::cout<<"empty......"<<endl;}Exiv2::Exifdatum& Modle_tag = exifData[exifDataName];std::string valueOfTag = Modle_tag.toString();std::cout<<exifDataName<<" is "<<valueOfTag<<std::endl;return valueOfTag;}

方法2

std::string getValueOfTag2(std::string filepath, std::string &exifDataName)
{Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filepath);if(image.get() == 0)cout<<"failed to opened..."<<endl;image->readMetadata();Exiv2::ExifData &exifData = image->exifData();if (exifData.empty()) {std::cout<<"empty......"<<endl;}Exiv2::ExifKey key(exifDataName);Exiv2::ExifData::const_iterator i = exifData.findKey(key);std::cout << "key is "<< i->key() <<std::endl;//the name of key//    std::cout << "Tag(hex) is "<< "0x" << std::hex << i->tag() << std::endl;//    std::cout << "Type is "<< i->typeName() << std::endl;//    std::cout << "Tag(dec) is "<< std::dec << i->count() <<std::endl;//    std::cout << "Value of tag is "<< std::dec << i->value()<<std::endl;std::cout << "Value of tag is "<< i->value()<<std::endl;string valueOfTag = "yeah!";return valueOfTag;}

使用时只需要在main中直接调用这其中一个函数即可,注意图片的路径!

四、小结

该库可供读写的选项十分丰富,但是也存在不足(也可能时个人原因委屈)。比如在获取信息的GPS数据的精度问题上,只能够保留四个小数位,误差太大,误差还是很大的,略有不足,但是镜头焦距上,有更高的准确度。如果朋友们能够读取更高精度的GPS信息,请告知一下,谢谢~

相关链接:

http://exiv2.dyndns.org:8080/

http://www.exiv2.org/download.html    

exif信息查询:

https://exif.tuchong.com/ 

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: