Python, ignore files with no Exif data

时间:2017-07-17 15:29:31

标签: python python-3.x glob exif pillow

I am trying to do a mass extraction of gps exif data, my code below:

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

Code source

Which is run like:

if __name__ == "__main__":
    image = Image.open("photo directory")
    exif_data = get_exif_data(image)
    print(get_lat_lon(exif_data)

This works fine for one photo, so I've used glob to iterate over all photos in a file:

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 

Which works fine, as long as every photo in the file is a) an image and b) has gps data. I have tried adding a pass in the _get_if_exist function as well as my file iteration, however, neither same to have had any impact and I'm still receiving KeyError: 'GPSInfo'

Any ideas on how I can ignore photos with no data or different file types?

2 个答案:

答案 0 :(得分:0)

一种可能的方法是编写一个小助手函数,如果文件实际上是图像文件则首先检查,第二步检查图像是否包含EXIF数据。

def is_metadata_image(filename):
    try:
        image = Image.open(filename)
        return 'exif' in image.info
    except OSError:
        return False

我发现在使用.png时,每次使用包含EXIF信息的_getexif()个文件时,PIL都不起作用。因此,我会在图片的exif字典中检查密钥info

答案 1 :(得分:0)

我已经尝试过这个源代码。 只需删除

gps_info = exif_data["GPSInfo"]

get_lat_lon(exif_data) 函数的第一行开始,它对我来说效果很好。