2017-07-17 3 views
0

Je suis en train de faire une extraction massive des données exif gps, mon code ci-dessous:Python, ignorer les fichiers sans données 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 

Code source

Ce qui est géré comme:

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

Cela fonctionne très bien pour une photo, j'ai donc utilisé glob pour itérer sur toutes les photos dans un fichier:

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 

Ce qui fonctionne bien, à condition que chaque photo dans le fichier est a) une image et b) a des données GPS. J'ai essayé d'ajouter une passe dans la fonction _get_if_exist ainsi que l'itération de mon fichier, cependant, ni l'un ni l'autre n'a eu d'impact et je reçois toujours

Toutes les idées sur la façon dont je peux ignorer des photos sans données ou différentes types de fichier?

+2

Avez-vous essayé 'try:' 'except KeyError:'? https://docs.python.org/3/tutorial/errors.html –

+1

Ou 'si 'GPSInfo' dans exif_data: ..', etc. – 9000

+0

Merci à tous les deux, appréciez ça! – Maverick

Répondre

0

Une approche possible serait d'écrire une petite fonction d'aide qui vérifie d'abord, si le fichier est en fait un fichier image et dans un second temps vérifie si l'image contient des données EXIF.

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

Je trouve que PIL ne fonctionne pas à chaque fois avec .png fichiers qui ne contiennent des informations EXIF ​​lors de l'utilisation _getexif(). Donc à la place je vérifie la clé exif dans le dictionnaire info d'une image.