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.")
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]:
In [ ]: