Skip to content

Instantly share code, notes, and snippets.

@wiedi
Created November 23, 2019 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wiedi/e5ccb06e7f65e134753f4344ce6040db to your computer and use it in GitHub Desktop.
Save wiedi/e5ccb06e7f65e134753f4344ce6040db to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import os
import shutil
from PIL import Image, ExifTags
def full_output_path(args, entry):
return args.output_dir + '/full/' + entry.name
def thumb_output_path(args, entry):
return args.output_dir + '/thumb/' + entry.name
def exif_rotate(img):
exif_tags = dict([(x[1], x[0]) for x in ExifTags.TAGS.items()])
orientation = 1
try:
orientation = img._getexif()[exif_tags['Orientation']]
except:
pass
if orientation == 1:
return img
elif orientation == 2:
return img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 3:
return img.transpose(Image.ROTATE_180)
elif orientation == 4:
return img.transpose(Image.FLIP_TOP_BOTTOM)
elif orientation == 5:
return img.transpose(Image.FLIP_LEFT_RIGHT).transpose(Image.ROTATE_90)
elif orientation == 6:
return img.transpose(Image.ROTATE_270)
elif orientation == 7:
return img.transpose(Image.FLIP_TOP_BOTTOM).transpose(Image.ROTATE_90)
elif orientation == 8:
return img.transpose(Image.ROTATE_90)
return img
def generate_html(args, imgs):
tpl_head = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>""" + args.image_dir + """</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
background: #222;
margin: 0;
padding: 5px;
margin-bottom: 20px;
}
@media (max-width: 1460px) {
.thumb { width: calc(50% - 10px); }
}
@media (min-width: 1460px) and (max-width: 2190px) {
.thumb { width: calc(33.33329% - 10px); }
}
@media (min-width: 2190px) and (max-width: 2920px) {
.thumb { width: calc(25% - 10px); }
}
@media (min-width: 2920px) {
.thumb { width: calc(20% - 10px); }
}
.thumb {
margin: 5px;
padding: 0;
border: none;
float: left;
}
</style>
</head>
<body>
"""
tpl_img = """<a href="full/{img_name}"><img class="thumb" src="thumb/{img_name}"></a>"""
tpl_foot = """
</body>
</html>
"""
with open(args.output_dir + '/index.html', 'w') as f:
f.write(tpl_head)
for i in imgs:
f.write(tpl_img.format(img_name = i.name))
f.write(tpl_foot)
def lookup_images(args):
img_list = []
for entry in os.scandir(args.image_dir):
if not entry.is_file():
continue
if not entry.name.split('.')[-1].lower() in ['png', 'jpg', 'jpeg']:
continue
img_list += [entry]
return sorted(img_list, key = lambda e: e.name)
def copy_images(args, img_list):
for f in img_list:
# create rotate full img
img = Image.open(f.path)
img = exif_rotate(img)
img.save(full_output_path(args, f))
# create thumbs
img = Image.open(f.path)
img = exif_rotate(img)
img.thumbnail((720, 10000))
img.save(thumb_output_path(args, f))
def mkstatic(args):
img_list = lookup_images(args)
if not img_list:
print("No image files found")
return
# create dirs
try:
os.makedirs(args.output_dir + '/full')
os.makedirs(args.output_dir + '/thumb')
except OSError:
print("Output dir already exists")
return
copy_images(args, img_list)
generate_html(args, img_list)
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--output-dir', help='directory where the gallery will be written', default='./gallery')
parser.add_argument('image_dir', help='directory with original images')
args = parser.parse_args()
mkstatic(args)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment