1、背景
每張圖片都包含EXIF信息,它是可交換圖像文件的縮寫,是專門為數碼相機的照片設定的,可以記錄數碼照片的屬性信息和拍攝數據。EXIF可以附加於JPEG、TIFF、RIFF等文件之中,為其增加有關數碼相機拍攝信息的內容和索引圖或圖像處理軟件的版本信息。總結來說EXIF信息包含着該照片的拍照基本信息。
網上有很多的EXIF信息查看器,這里上傳一張十月一日和朋友去觀看的我和我的祖國這部電影的照片,沒有任何的標志建築背景,使用該工具進行嘗試,可以很直觀的看到拍照時間、手機型號、地理位置等信息,具體如下所示:
接下來通過Python exifread庫函數解析照片,它可以解析圖片的EXIF信息,進而依托百度地圖開放平台將GPS坐標信息轉換為具體的位置,若想達到理想效果需要滿足以下幾點要求:
他人通過選擇原圖的方式,發送照片;
相機拍照時,默認設置了GPS定位;
圖片沒P過;
2、雲端部署
第1步:登錄百度地圖開放平台,進入控制台,這里說明一下,百度地圖開放平台的定位有Web開發、Android開發
iOS開發等不同的服務,最終均會生成服務密鑰(AK),我們的Python調用就是依托於服務密鑰,所以創建什么業務影響不大,故不看開發文檔也可以很方便開發。
第2步:創建應用,這里我選擇應用類型為:服務端(什么類型都不影響接下來的操作,重點是獲取服務密鑰)。
這樣就操作完成了,使用獲取的服務密鑰就可以實現訪問。
最后拓展學習,看一下開發文檔 ,主要是不同終端設備的SDK說明文檔,有需要的小伙伴可以針對學習。
3、照片分析
依舊使用該照片做測試。
分析代碼如下:
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信息查看器解析一致,分析結果如下:
作者:華為雲特約供稿開發者 不脫發的程序猿