利用Python實(shí)現(xiàn)讀取照片的Exif信息
今天要水的文章是,用 Python 讀取照片的 Exif 信息。現(xiàn)如今的智能手機(jī)在拍攝照片時(shí),都含有 Exif(可交換圖像文件格式,Exchangeable image file format)信息,通過該信息可以獲取拍照時(shí)的位置、時(shí)間,以及手機(jī)品牌等信息。那么下面就看看如何使用 Python 去獲取這些信息吧。
Python 想要讀取 Exif 信息需要安裝一個(gè)第三方庫,直接 pip install exifread 即可。
import exifread
with open("1.jpg", 'rb') as f:
# 直接可以拿到里面的信息,內(nèi)容非常多
# 但如果無法讀取,那么返回值 exif 就是 None
exif = exifread.process_file(f)
# 這里我們選一些常用的,里面的 value 需要轉(zhuǎn)成字符串
# 不轉(zhuǎn)成字符串的話看起來會(huì)比較費(fèi)勁
print("圖片寬度:", str(exif["Image ImageWidth"]))
print("圖片高度:", str(exif["Image ImageLength"]))
print("手機(jī)品牌:", str(exif["Image Make"]))
print("手機(jī)型號(hào):", str(exif["Image Model"]))
print("拍攝時(shí)間:", str(exif["Image DateTime"]))
print("經(jīng)度:", str(exif["GPS GPSLongitude"]))
print("東經(jīng)還是西經(jīng):", str(exif["GPS GPSLongitudeRef"]))
print("緯度:", str(exif["GPS GPSLatitude"]))
print("南緯還是北緯:", str(exif["GPS GPSLatitudeRef"]))
"""
圖片寬度: 3968
圖片高度: 2976
手機(jī)品牌: HUAWEI
手機(jī)型號(hào): EML-AL00
拍攝時(shí)間: 2021:07:08 19:52:23
經(jīng)度: [116, 28, 5973999/100000]
東經(jīng)還是西經(jīng): E
緯度: [39, 59, 1255371/200000]
南緯還是北緯: N
"""還是比較簡(jiǎn)單的,但是里面的經(jīng)度和緯度比較怪,我們還需要再對(duì)其轉(zhuǎn)化一下。
lng = str(exif["GPS GPSLongitude"]) # 經(jīng)度
lat = str(exif["GPS GPSLatitude"]) # 緯度
print(lng) # [116, 28, 5973999/100000]
print(lat) # [39, 59, 1255371/200000]
# 轉(zhuǎn)成列表
lng = lng[1: -1].replace("/", ",").split(",")
lat = lat[1: -1].replace("/", ",").split(",")
print(lat) # ['39', ' 59', ' 1255371', '200000']
print(lng) # ['116', ' 28', ' 5973999', '100000']
# 然后得到具體的經(jīng)緯度
lng = float(lng[0]) + float(lng[1]) / 60 + float(lng[2]) / float(lng[3]) / 3600
lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
print(lng) # 116.48326110833334
print(lat) # 39.98507690416667這里得到的經(jīng)緯度永遠(yuǎn)是正數(shù),如果是西經(jīng),那么得到的經(jīng)度要乘上 -1;同理如果是南緯,那么緯度要乘上 -1。
另外需要注意,并非所有的照片都能夠進(jìn)行解析,必須是攜帶 Exif 信息的原始圖片。如果中間進(jìn)行了壓縮、或者 P 圖,那么就無法識(shí)別了。
當(dāng)然像一些社交平臺(tái)也會(huì)專門針對(duì) Exif 進(jìn)行處理,比如微信,你發(fā)在朋友圈的圖片會(huì)自動(dòng)壓縮,所以是不會(huì)暴露位置信息的。
方法補(bǔ)充
除了上文的方法,小編還為大家整理了其他Python讀取圖片Exif信息的方法,需要的可以收藏一下
方法一:
示例代碼
import exifread
import requests
class PhotoExifInfo():
def __init__(self,photo_path):
self.photo_path = photo_path
self.baidu_map_ak = "your baidu map api key"
self.image_info_dict={}
self.tags ={}
self.interested_keys = [
'EXIF ExposureMode',
'EXIF ExposureTime',
'EXIF Flash',
'EXIF ISOSpeedRatings',
'Image Model',
'EXIF ExifImageWidth',
'EXIF ExifImageLength',
'Image DateTime',
'EXIF DateTimeOriginal',
'Image Make',
# lens
# jiaoju
]
def get_tags(self):
"""
獲取照片信息
"""
image_content = open(self.photo_path, 'rb')
tags = exifread.process_file(image_content)
self.tags = tags
for item in self.interested_keys:
try:
info = tags[item]
self.image_info_dict[item] = info
except:
print(f'{self.photo_path} has no attribute of {item}')
continue
# 遍歷獲取照片所有信息
#for j, k in tags.items():
#print(f"{j} : {k}")
#print('拍攝時(shí)間:', tags['EXIF DateTimeOriginal'])
#print('照相機(jī)制造商:', tags['Image Make'])
#print('照相機(jī)型號(hào):', tags['Image Model'])
#print('照片尺寸:', tags['EXIF ExifImageWidth'], tags['EXIF ExifImageLength'])
image_content.close()
def get_lng_lat(self):
"""經(jīng)緯度轉(zhuǎn)換"""
tags = self.tags
try:
# 緯度
LatRef = 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]) / 3600
if LatRef != "N":
Lat = Lat * (-1)
# 經(jīng)度
LonRef = 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]) / 3600
if LonRef != "E":
Lon = Lon * (-1)
return Lat,Lon
except:
print('Unable to get')
def get_city_info(self):
result = self.get_lng_lat()
if result:
Lat, Lon = result
url = "https://api.map.baidu.com/reverse_geocoding/v3/?ak="+self.baidu_map_ak+"&output=json&coordtype=wgs84ll&location=" + str(Lat) + ',' + str(Lon)
#url = "https://api.map.baidu.com/reverse_geocoding/v3/?ak="+self.baidu_map_ak+"&output=json&coordtype=wgs84ll&location=31.225696563611,121.49884033194"
response = requests.get(url).json()
status = response['status']
if status == 0:
address = response['result']['formatted_address']
if address != "":
self.image_info_dict['Position'] = address
else:
print('baidu_map error')
def get_image_info(self):
self.get_tags()
self.get_city_info()
return self.image_info_dict
if __name__ == '__main__':
result = PhotoExifInfo("test.jpeg").get_image_info()
for j, k in result.items():
print(f"{j} : {k}")示例輸出
EXIF ExposureMode : Auto Exposure
EXIF ExposureTime : 10/24723
EXIF Flash : Flash did not fire, auto mode
EXIF ISOSpeedRatings : 50
Image Model : vivo Z1
EXIF ExifImageWidth : 4144
EXIF ExifImageLength : 1968
Image DateTime : 2019:11:03 11:34:24
EXIF DateTimeOriginal : 2019:11:03 11:34:24
Image Make : vivo
Position : 上海市黃浦區(qū)中山南路187
方法二
示例代碼
import exifread
import json
import urllib.request
f = open('1.jpg', 'rb')
tags = exifread.process_file(f)
print(tags)
# 打印所有照片信息,會(huì)以鍵值對(duì)的方法保存
for tag in tags.keys():
print("Key: {0}, value {1}".format(tag, tags[tag]))
# 打印照片其中一些信息
print('拍攝時(shí)間:', tags['EXIF DateTimeOriginal'])
print('照相機(jī)制造商:', tags['Image Make'])
print('照相機(jī)型號(hào):', tags['Image Model'])
print('照片尺寸:', tags['EXIF ExifImageWidth'], tags['EXIF ExifImageLength'])
def getLatOrLng(refKey, tudeKey):
"""
獲取經(jīng)度或緯度
"""
if refKey not in tags:
return None
ref = tags[refKey].printable
LatOrLng = tags[tudeKey].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
print(LatOrLng)
LatOrLng = float(LatOrLng[0]) + float(LatOrLng[1]) / 60 + float(LatOrLng[2]) / 3600
if refKey == 'GPS GPSLatitudeRef' and tags[refKey].printable != "N":
LatOrLng = LatOrLng * (-1)
if refKey == 'GPS GPSLongitudeRef' and tags[refKey].printable != "E":
LatOrLng = LatOrLng * (-1)
return LatOrLng
# 調(diào)用百度地圖API通過經(jīng)緯度獲取位置
def getlocation(lat, lng):
"""
exif里面的經(jīng)緯度是度分秒形式傳入的,需要轉(zhuǎn)換為小數(shù)形式,然后根據(jù)傳入的經(jīng)緯度,調(diào)用百度接口去查詢?cè)敿?xì)地址
"""
url = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=百度API的AK信息,需要自己去申請(qǐng)&output=json&coordtype=wgs84ll&language_auto=1&extensions_town=true&location=" + lat + "," + lng
req = urllib.request.urlopen(url)
res = req.read().decode("utf-8")
print(res)
str1 = json.loads(res)
jsonResult = str1.get('result')
formatted_address = jsonResult.get('formatted_address')
return formatted_address
lat = getLatOrLng('GPS GPSLatitudeRef', 'GPS GPSLatitude') # 緯度
lng = getLatOrLng('GPS GPSLongitudeRef', 'GPS GPSLongitude') # 經(jīng)度
print('緯度:{0} 經(jīng)度:{1}'.format(lat, lng))
location = getlocation(str(lat), str(lng))
print('位置:{0}'.format(location))到此這篇關(guān)于利用Python實(shí)現(xiàn)讀取照片的Exif信息的文章就介紹到這了,更多相關(guān)python讀取照片Exif信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Win10操作系統(tǒng)中PyTorch虛擬環(huán)境配置+PyCharm配置
本文主要介紹了Win10操作系統(tǒng)中PyTorch虛擬環(huán)境配置+PyCharm配置,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
python人工智能使用RepVgg實(shí)現(xiàn)圖像分類示例詳解
這篇文章主要介紹了python人工智能使用RepVgg實(shí)現(xiàn)圖像分類示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Python While循環(huán)語句實(shí)例演示及原理解析
這篇文章主要介紹了Python While循環(huán)語句實(shí)例演示及原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
python?dataframe獲得指定行列實(shí)戰(zhàn)代碼
對(duì)于一個(gè)DataFrame,常常需要篩選出某列為指定值的行,下面這篇文章主要給大家介紹了關(guān)于python?dataframe獲得指定行列的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
Python使用asyncio異步時(shí)的常見問題總結(jié)
這篇文章主要為大家整理了開發(fā)人員在?Python?中使用?asyncio?時(shí)提出的常見問題以及解決方法,文中的示例代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下2023-04-04

