使用 python 提取照片中的手机信息
最近在做一个项目,有一个很重要的点是需要获取使用用户的手机信息,这里我选择从照片中获取信息。有人会问为什么不从手机里面直接获取设备信息。由于现在android系统的权限设置做的越来越好,直接获取信息很可能被认定为非法获取用户隐私,所以不打算使用这个思路。
我的思路是,获取用户上传的图片中的信息,这样就可以尽量减少用户手机上的权限申请数量,让我们的应用更加受欢迎,(试想一个APP一装上来就请求十几二十个一大堆权限列表,你会开心的去安装吗)。正好应用的一个功能需要用户上传图片,正好顺带这个功能把一些数据获取功能做了,岂不是两全其美,一石二鸟。下面简单介绍下这个技术。
0x01 为什么可以通过图片获取手机信息
在现代的数码相机保存的图片中,有一个分区叫做 EXIF
, 正是它的存在保证了可以通过图片获取手机的一些参数。下面是维基百科关于EXIF
的介绍:
可交换图像文件格式(英语:Exchangeable image file format,官方简称Exif),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。
Exif可以附加于JPEG、TIFF、RIFF等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。*
wiki上的内容至少告诉我们两点:
一是这个 EXIF 是专门设计来为数码相机保存照片属性设计的。
二是这个 EXIF 是可以附加在常见的各种图片格式中的
正是这些特性让我们可以从图片中提取手机设备的信息。
0x02 通过 Python 提取 EXIF 中的信息
只要掌握了其格式, 理论上可以通过各种编程语言对 EXIF 数据进行提取。由于我们的应用后端是 python 开发的,所以这里介绍如何用 python 进行提取。
感谢强大的python, 很多现成的库供我们调用, 直接使用PIL库就可以完成这项工作, 首先你需要安装这个库:
pip install pillow
下面是核心代码,基本的思路就是先通过 PIL.Image 读取图片,然后根据 PIL.ExifTags 中的关键字生成手机参数字典,字典生成出来了,至于这些数据怎么用就八仙过海,各显申通了。下面是实现代码:
import PIL.Image
import PIL.ExifTags
import sys
if len(sys.argv) != 2:
print("Usage: {} image_file".format(sys.arg[0]))
exit()
# 通过 PIL.Image.open 读取图片
img = PIL.Image.open(sys.argv[1])
# 生成手机参数数据字典
exif = {
PIL.ExifTags.TAGS[k]: v
for k, v in img._getexif().items()
if k in PIL.ExifTags.TAGS
}
# 打印这些信息
for info in exif:
print(info, end=':')
print(exif[info])
运行后得到的结果(有的关键信息我已经打了马赛克,或者删了,毕竟隐私嘛。):
(imageExif) λ python get_exif.py IMG20190324132051.jpg
GPSInfo: 马赛克 :)
ResolutionUnit:2
ExifOffset:250
Make:OPPO
Model:OPPO R11
DateTime:2019:03:24 13:20:51
Flash:16
......
注意看数据,
如 GPSInfo
信息记录了在拍摄这张照片时用户所处的地理位置,同时记录了拍摄时间。
如 Make
字段记录了用户也难怪的什么手机 这里我用的是 OPPO R11。
当然,其他语言也可做这个,欢迎讨论。