In [1]:
from PIL import Image, ExifTags
import getexifdata, glob, os, json, io, shutil, logprogress

DIR_PLACES = "../Places/"
DIR_KML = "kml/"
DIR_AUD = "aud/"
DIR_IMG_ORIG = "img/"
DIR_IMG_THUMBNAIL = "imgSm/"
DIR_IMG_ERR = "imgErr/"

IMG_FORMAT = ".jpg"
AUD_FORMAT = ".mp3"

INPUT_JSON = "info_template.json"
OUTPUT_JSON = "info.json"

SIZE_IMG_THUMBNAIL = 400

# process every dir in Places/
placels = glob.glob(DIR_PLACES + "*/")

# or maybe only process a single place
placels = [DIR_PLACES + "YubaRiver/"]

# process each directory
for base_path in logprogress.log_progress(placels):
    
    print("processing place: " + base_path)
    
    # clear workspace
    try:
        shutil.rmtree(base_path + DIR_IMG_THUMBNAIL)
        os.makedirs(base_path + DIR_IMG_THUMBNAIL)
        shutil.rmtree(base_path + DIR_IMG_ERR)
        os.makedirs(base_path + DIR_IMG_ERR)
    except FileNotFoundError:
        print("missing img dirs for: " + base_path)

    ####################
    ###
    ### helper functions
    ###
    
    def strip_dir(fpath, dir):
        i = fpath.index(dir)+len(dir)
        return fpath[i:len(fpath)]

    def get_fname(fpath):
        return fpath.split("/")[-1]

    def get_flabel(fpath, ext):
        return get_fname(fpath).replace(ext, "")

    def find_audio_for_img(label):
        for fpath in glob.glob(base_path + DIR_AUD + "*" + AUD_FORMAT):
            flabel = get_flabel(fpath, AUD_FORMAT)
            if flabel == label:
                return strip_dir(fpath, "/" + DIR_AUD)
        return None # no warning needed
    
    def save_err_img(fpath, msg):
        print(msg + " : " + fpath)
        im = Image.open(fpath)
        im.save(base_path + DIR_IMG_ERR + get_fname(fpath).replace(IMG_FORMAT, "") + "_" + msg + IMG_FORMAT)
    
    def get_gps_for_fpath(fpath):
        im = Image.open(fpath)
        edat = getexifdata.get_exif_data(im)
        lat, lng = getexifdata.get_lat_lon(edat)
        if lat == None or lng == None:
            save_err_img(fpath, "WARNING! no gps data for image")
            return None
        else:
            return {"lat":lat, "lng":lng}

    try:
        to_unicode = unicode
    except NameError:
        to_unicode = str    
    
    def find_kml():
        return [strip_dir(fpath, "/" + DIR_KML) for fpath in glob.glob(base_path + DIR_KML + "*.kml")]
    
    def reorient_img(fileName, height):
        # thanks storm_to : http://stackoverflow.com/questions/4228530/pil-thumbnail-is-rotating-my-image 
        fpath = base_path + DIR_IMG_ORIG + fileName
        image=Image.open(fpath)
        exif_raw = image._getexif()
        if (exif_raw):
            for orientation in ExifTags.TAGS.keys() : 
                if ExifTags.TAGS[orientation]=='Orientation' : break 
            exif=dict(exif_raw.items())
            
            try:
                if   exif[orientation] == 3 : 
                    image=image.rotate(180, expand=True)
                elif exif[orientation] == 6 : 
                    image=image.rotate(270, expand=True)
                elif exif[orientation] == 8 : 
                    image=image.rotate(90, expand=True)
            except KeyError:
                False
                #print("No orientation EXIF data for: " + fileName)
        
        # thumnail
        r = float(height) / image.size[1]
        w = float(image.size[0]) * r
        image.thumbnail((w, height), Image.ANTIALIAS)
        image.save(base_path + DIR_IMG_THUMBNAIL + fileName)

    ####################
    ###
    ### sanity check
    ###

    # sanity check: every audio file should have a matching img
    def ensure_audio_img_match():
        # error if an audio file has no image. slow, but we should ensure this.
        for fpath in glob.glob(base_path + DIR_AUD + "*" + AUD_FORMAT):
            match = False
            for imgpath in glob.glob(base_path + DIR_IMG_ORIG + "*" + IMG_FORMAT):
                if get_flabel(imgpath, IMG_FORMAT) == get_flabel(fpath, AUD_FORMAT):
                    match = True
            if not match:
                #raise FileNotFoundError("no image for audio file: " + fpath)
                return True

    # sanity check: every image should have GPS coordinates
    def ensure_img_gps():
        [get_gps_for_fpath(fpath) for fpath in glob.glob(base_path + DIR_IMG_ORIG + "*" + IMG_FORMAT)]

    ####################
    ###
    ### run
    ###
    ensure_img_gps()
    ensure_audio_img_match()

    # read json template
    with open(base_path + INPUT_JSON) as data_file:
        data = json.load(data_file)
        data["layers"] = find_kml()

        # for every image...
        files = glob.glob(base_path + DIR_IMG_ORIG + "*" + IMG_FORMAT)
        for fpath in logprogress.log_progress(files):
            
            # compile location info
            flabel = get_flabel(fpath, IMG_FORMAT)
            fnam = get_fname(fpath)
            
            #print("processing: " + fnam)
            
            marker = {
                "label": flabel,
                "loc": get_gps_for_fpath(fpath),
                "img": fnam,
                "aud": find_audio_for_img(flabel)
            }
            data["locations"].append(marker)
            
            # save web-friendly image (rotated & small)
            reorient_img(fnam, SIZE_IMG_THUMBNAIL)
        
        # Write JSON file
        # http://stackoverflow.com/questions/12309269/how-do-i-write-json-data-to-a-file-in-python
        with io.open(base_path + OUTPUT_JSON, 'w', encoding='utf8') as outfile:
            str_ = json.dumps(data,
                              indent=4, sort_keys=True,
                              separators=(',', ':'), ensure_ascii=False)
            outfile.write(to_unicode(str_))
        
print("done.")


processing place: ../Places/EelRiver/
WARNING! no gps data for image : ../Places/EelRiver/img/2017-08-12 15.17.46 HDR.jpg
WARNING! no gps data for image : ../Places/EelRiver/img/2017-08-12 15.17.46 HDR.jpg
done.

In [2]:
from PIL import Image, ExifTags
import getexifdata, glob, os, json, io, shutil, logprogress

DIR_PLACES = "../Places/"
DIR_KML = "kml/"
DIR_AUD = "aud/"
DIR_IMG_ORIG = "img/"
DIR_IMG_THUMBNAIL = "imgSm/"
DIR_IMG_ERR = "imgErr/"

IMG_FORMAT = ".jpg"
AUD_FORMAT = ".mp3"

INPUT_JSON = "info_template.json"
OUTPUT_JSON = "info.json"

SIZE_IMG_THUMBNAIL = 400

# process every dir in Places/
placels = glob.glob(DIR_PLACES + "*/")
placels


Out[2]:
['../Places/SanJoaquinRiver/',
 '../Places/FeatherRiver/',
 '../Places/RussianRiver/',
 '../Places/CostaRica/',
 '../Places/SFWatershed/',
 '../Places/EelRiver/']

In [ ]: