使用 python 提取照片中的手机信息
使用 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。
当然,其他语言也可做这个,欢迎讨论。
使用 python 提取照片中的手机信息的更多相关文章
- Python 日志输出中添加上下文信息
Python日志输出中添加上下文信息 除了传递给日志记录函数的参数(如msg)外,有时候我们还想在日志输出中包含一些额外的上下文信息.比如,在一个网络应用中,可能希望在日志中记录客户端的特定信息,如: ...
- python+adb实现自动化获取手机信息
首先我们先看一下使用adb查看Android手机信息的指令 #获取手机名称NAME = 'adb shell getprop ro.product.model'#获取手机版本VERSION = 'ad ...
- python提取mysql中指定列参数,并循环打印
试验环境: Python 3.7.0 Mysql 5.0 实验目的: 使用python将数据库中指定的列中的数值取出来,并循环遍历,用以当成参数传递给需要它的方法. 本次实验取的是para列的数据 实 ...
- python 提取目录中特定类型的文件
python使用‘os’和‘re’模块提取目录中特定类型的文件,这两个模都是安装python自带的,所以不需要安装. 思路: 使用os库lilstdir获取文件夹中的所有文件名,然后带上文件夹路径组合 ...
- python提取文件中的方法名称
#提取文件中的方法名称 # -*- coding:utf-8 -*- def Query_Method(filepath): file = open(filepath,'r',encoding= 'U ...
- 使用正则提取字符串中URL等信息
一.说明 背景:最近在做同步京东商品信息时遇到一个问题,同步后的商品详情无法在富文本中修改,强制修改会导致图片无法正常显示,研究发现详情中的图片是在css的作为背景图指定的. 解决:经过多次尝试,最后 ...
- 照片元数据信息以及在照片中写入gps信息
/// 照片元数据编码 在下面的文章里,可以看到图片所有的元数据定义信息 https://msdn.microsoft.com/zh-cn/library/system.drawing.imaging ...
- 如何用Python输出PPT中的文字信息
在这里,会用到win32com模块 模块下载地址:http://sourceforge.net/projects/pywin32/files/pywin32/ 代码如下: import win32co ...
- python 提取字符串中的指定字符 正则表达式
例1: 字符串: '湖南省长沙市岳麓区麓山南路麓山门' 提取:湖南,长沙 在不用正则表达式的情况下: address = '湖南省长沙市岳麓区麓山南路麓山门' address1 = address.s ...
随机推荐
- Method for finding shortest path to destination in traffic network using Dijkstra algorithm or Floyd-warshall algorithm
A method is presented for finding a shortest path from a starting place to a destination place in a ...
- Creating Apps With Material Design —— Defining Custom Animations
转载请注明 http://blog.csdn.net/eclipsexys 翻译自Developer Android,时间仓促,有翻译问题请留言指出.谢谢 定义动画 在材料设计动画让用户与您的应用程序 ...
- PHP 挖掘 XML 和 HTML 数据
数据挖掘及其重要性 常用缩略词 API: 应用程序编程接口 CDATA: 字符数据 DOM: 文档对象模式 FTP: 文件传输协议 HTML: 超文本标记语言 HTTP: 超文本传输协议 REST: ...
- Android Ant 和 Gradle 包装工艺和效率控制
一个.Ant 包:(下载ant.配置环境变量不说) 1.进入命令行模式,并切换到项目文件夹,运行例如以下命令为ADT创建的项目加入ant build支持: android update project ...
- Swift现实
笔者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/34540623 转载请注明出处 假设认为文章对你有所帮助,请通过留言 ...
- 各种Message中文解释(一部分)
函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.该函数是应用程序和应用程序之间进行消息传递的主要手段之一. 函数原型:LRESUL ...
- 阿里云访问控制(RAM)授权子账户管理磁盘快照
阿里云 RAM 控制台没有提供管理磁盘快照的系统策略,需要自己添加自定义授权策略. 操作步骤: 进入 RAM 控制台 -> 策略管理,点击"新建授权策略" 选中"空 ...
- JS如何为iframe添加onclick事件
如果页面上有iframe时,鼠标点击在iframe内时,包含iframe的document是不响应任何事件的, 例如: $("#iframe1").click(function() ...
- iOS UITableView动态隐藏或显示Item
通过改变要隐藏的item的高度实现隐藏和显示item 1.创建UITableView #import "ViewController.h" @interface ViewContr ...
- String内存结构
var s: AnsiString; begin s := '1234567890'; showmessage(s); end; 变量s的内存结构为A8 03 01 00 FF FF FF FF 0A ...