Python解析照片EXIF信息,获取坐标位置

举报
yd_278972944 发表于 2020/07/28 10:38:30 2020/07/28
【摘要】 每张图片都包含EXIF信息,它是可交换图像文件的缩写,是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。EXIF可以附加于JPEG、TIFF、RIFF等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。总结来说EXIF信息包含着该照片的拍照基本信息。

1、背景

每张图片都包含EXIF信息,它是可交换图像文件的缩写,是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。EXIF可以附加于JPEG、TIFF、RIFF等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。总结来说EXIF信息包含着该照片的拍照基本信息。


网上有很多的EXIF信息查看器,这里上传一张十月一日和朋友去观看的我和我的祖国这部电影的照片,没有任何的标志建筑背景,使用该工具进行尝试,可以很直观的看到拍照时间、手机型号、地理位置等信息,具体如下所示:

image.png

image.png

image.png

image.png

image.png


接下来通过Python exifread库函数解析照片,它可以解析图片的EXIF信息,进而依托百度地图开放平台将GPS坐标信息转换为具体的位置,若想达到理想效果需要满足以下几点要求:


他人通过选择原图的方式,发送照片;

相机拍照时,默认设置了GPS定位;

图片没P过;


2、云端部署

第1步:登录百度地图开放平台,进入控制台,这里说明一下,百度地图开放平台的定位有Web开发、Android开发

iOS开发等不同的服务,最终均会生成服务密钥(AK),我们的Python调用就是依托于服务密钥,所以创建什么业务影响不大,故不看开发文档也可以很方便开发。

image.png


第2步:创建应用,这里我选择应用类型为:服务端(什么类型都不影响接下来的操作,重点是获取服务密钥)。

image.png

image.png

这样就操作完成了,使用获取的服务密钥就可以实现访问。

image.png

 最后拓展学习,看一下开发文档 ,主要是不同终端设备的SDK说明文档,有需要的小伙伴可以针对学习。

image.png

3、照片分析

依旧使用该照片做测试。

image.png

 分析代码如下:

import requests
import exifread
 
class GetPhotoInfo:
    def __init__(self, photo):
        self.photo = photo
        # 百度地图ak  请替换为自己申请的ak
        self.ak = 'nYPs4LQ9a4VhVxj55AD69K6zgsRy9o4z'
        self.location = self.get_photo_info()
 
    def get_photo_info(self, ):
        with open(self.photo, 'rb') as f:
            tags = exifread.process_file(f)
        try:
            # 打印照片其中一些信息
            print('拍摄时间:', tags['EXIF DateTimeOriginal'])
            print('照相机制造商:', tags['Image Make'])
            print('照相机型号:', tags['Image Model'])
            print('照片尺寸:', tags['EXIF ExifImageWidth'], tags['EXIF ExifImageLength'])
            # 纬度
            lat_ref = tags["GPS GPSLatitudeRef"].printable
            lat = tags["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
            lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
            if lat_ref != "N":
                lat = lat * (-1)
            # 经度
            lon_ref = tags["GPS GPSLongitudeRef"].printable
            lon = tags["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
            lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600
            if lon_ref != "E":
                lon = lon * (-1)
        except KeyError:
            return "ERROR:请确保照片包含经纬度等EXIF信息。"
        else:
            print("经纬度:", lat, lon)
            return lat, lon
 
    def get_location(self):
        url = 'http://api.map.baidu.com/reverse_geocoding/v3/?ak={}&output=json' \
              '&coordtype=wgs84ll&location={},{}'.format(self.ak, *self.location)
        response = requests.get(url).json()
        status = response['status']
        if status == 0:
            address = response['result']['formatted_address']
            print('详细地址:', address)
        else:
            print('baidu_map error')
 
 
if __name__ == '__main__':
    Main = GetPhotoInfo('im1.jpg')
    Main.get_location()


虽然地理位置和实际看电影的地点存在一些偏差,但是基本信息是挺准的,和EXIF信息查看器解析一致,分析结果如下:


作者:华为云特约供稿开发者  不脱发的程序猿 

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。