Python,忽略没有 Exif 数据的文件
Python, ignore files with no Exif data
我正在尝试大量提取 gps exif 数据,我的代码如下:
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
def get_exif_data(image):
exif_data = {}
info = image._getexif()
if info:
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
if decoded == "GPSInfo":
gps_data = {}
for t in value:
sub_decoded = GPSTAGS.get(t, t)
gps_data[sub_decoded] = value[t]
exif_data[decoded] = gps_data
else:
exif_data[decoded] = value
return exif_data
def _get_if_exist(data, key):
if key in data:
return data[key]
else:
pass
def get_lat_lon(exif_data):
gps_info = exif_data["GPSInfo"]
lat = None
lon = None
if "GPSInfo" in exif_data:
gps_info = exif_data["GPSInfo"]
gps_latitude = _get_if_exist(gps_info, "GPSLatitude")
gps_latitude_ref = _get_if_exist(gps_info, "GPSLatitudeRef")
gps_longitude = _get_if_exist(gps_info, "GPSLongitude")
gps_longitude_ref = _get_if_exist(gps_info, "GPSLongitudeRef")
if gps_latitude and gps_latitude_ref and gps_longitude and gps_longitude_ref:
lat = _convert_to_degrees(gps_latitude)
if gps_latitude_ref != "N":
lat = 0 - lat
lon = _convert_to_degrees(gps_longitude)
if gps_longitude_ref != "E":
lon = 0 - lon
return lat, lon
运行 就像:
if __name__ == "__main__":
image = Image.open("photo directory")
exif_data = get_exif_data(image)
print(get_lat_lon(exif_data)
这适用于一张照片,所以我使用 glob 遍历文件中的所有照片:
import glob
file_names = []
for name in glob.glob(photo directory):
file_names.append(name)
for item in file_names:
if __name__ == "__main__":
image = Image.open(item)
exif_data = get_exif_data(image)
print(get_lat_lon(exif_data))
else:
pass
只要文件中的每张照片 a) 图像和 b) 具有 gps 数据,就可以正常工作。我已经尝试在 _get_if_exist
函数中添加一个 pass 以及我的文件迭代,但是,两者都没有产生任何影响,我仍然收到 KeyError: 'GPSInfo'
关于如何忽略没有数据或不同文件类型的照片有什么想法吗?
一种可能的方法是编写一个小的辅助函数,首先检查文件是否实际上是图像文件,然后检查图像是否包含 EXIF 数据。
def is_metadata_image(filename):
try:
image = Image.open(filename)
return 'exif' in image.info
except OSError:
return False
我发现在使用 _getexif()
时,PIL 每次都无法处理包含 EXIF 信息的 .png
文件。因此,我改为在图像的 info
字典中检查键 exif
。
我试过这个源代码。
您只需要删除
gps_info = exif_data["GPSInfo"]
从get_lat_lon(exif_data)
函数的第一行开始,对我来说效果很好。
我正在尝试大量提取 gps exif 数据,我的代码如下:
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
def get_exif_data(image):
exif_data = {}
info = image._getexif()
if info:
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
if decoded == "GPSInfo":
gps_data = {}
for t in value:
sub_decoded = GPSTAGS.get(t, t)
gps_data[sub_decoded] = value[t]
exif_data[decoded] = gps_data
else:
exif_data[decoded] = value
return exif_data
def _get_if_exist(data, key):
if key in data:
return data[key]
else:
pass
def get_lat_lon(exif_data):
gps_info = exif_data["GPSInfo"]
lat = None
lon = None
if "GPSInfo" in exif_data:
gps_info = exif_data["GPSInfo"]
gps_latitude = _get_if_exist(gps_info, "GPSLatitude")
gps_latitude_ref = _get_if_exist(gps_info, "GPSLatitudeRef")
gps_longitude = _get_if_exist(gps_info, "GPSLongitude")
gps_longitude_ref = _get_if_exist(gps_info, "GPSLongitudeRef")
if gps_latitude and gps_latitude_ref and gps_longitude and gps_longitude_ref:
lat = _convert_to_degrees(gps_latitude)
if gps_latitude_ref != "N":
lat = 0 - lat
lon = _convert_to_degrees(gps_longitude)
if gps_longitude_ref != "E":
lon = 0 - lon
return lat, lon
运行 就像:
if __name__ == "__main__":
image = Image.open("photo directory")
exif_data = get_exif_data(image)
print(get_lat_lon(exif_data)
这适用于一张照片,所以我使用 glob 遍历文件中的所有照片:
import glob
file_names = []
for name in glob.glob(photo directory):
file_names.append(name)
for item in file_names:
if __name__ == "__main__":
image = Image.open(item)
exif_data = get_exif_data(image)
print(get_lat_lon(exif_data))
else:
pass
只要文件中的每张照片 a) 图像和 b) 具有 gps 数据,就可以正常工作。我已经尝试在 _get_if_exist
函数中添加一个 pass 以及我的文件迭代,但是,两者都没有产生任何影响,我仍然收到 KeyError: 'GPSInfo'
关于如何忽略没有数据或不同文件类型的照片有什么想法吗?
一种可能的方法是编写一个小的辅助函数,首先检查文件是否实际上是图像文件,然后检查图像是否包含 EXIF 数据。
def is_metadata_image(filename):
try:
image = Image.open(filename)
return 'exif' in image.info
except OSError:
return False
我发现在使用 _getexif()
时,PIL 每次都无法处理包含 EXIF 信息的 .png
文件。因此,我改为在图像的 info
字典中检查键 exif
。
我试过这个源代码。 您只需要删除
gps_info = exif_data["GPSInfo"]
从get_lat_lon(exif_data)
函数的第一行开始,对我来说效果很好。