This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# | |
# photobooth.py | |
# | |
# Based on py-slideshow by Corey Goldberg | |
# Copyright (c) 2013, 2015, Corey Goldberg | |
# Copyright (c) 2019-2020 Adam Kent | |
# | |
# Dev: https://github.com/cgoldberg/py-slideshow | |
# License: GPLv3 | |
import argparse | |
import random | |
import os | |
import glob | |
import time | |
import collections | |
import pyglet | |
import exifread | |
TICK = 3.0 | |
displayed = collections.Counter() | |
def get_image_paths(input_dir='.'): | |
paths = glob.glob(os.path.join(input_dir, '*.JPG')) | |
return paths | |
def display_it(imgFile): | |
img = pyglet.image.load(imgFile) | |
sprite.image = img | |
rotated = False | |
with open(imgFile, 'rb') as f: | |
metadata = exifread.process_file(f) | |
for tag in metadata.keys(): | |
if tag in ('Image Orientation'): | |
tagv = "%s" % metadata[tag] | |
if '90 CW' in tagv: | |
sprite.rotation = 90 | |
sprite.scale = (float(window.height) / img.height * 0.9) | |
sprite.x = window.width * 0.22 | |
sprite.y = window.height | |
elif '90 CCW' in tagv: | |
sprite.rotation = 270 | |
sprite.scale = (float(window.height) / img.height * 0.9) | |
sprite.x = window.width * 0.78 | |
sprite.y = 0 | |
else: | |
sprite.rotation = 0 | |
sprite.scale = (float(window.width) / img.width) | |
sprite.x = 0 | |
sprite.y = 0 | |
displayed.update([imgFile]) | |
def update_image(dt): | |
image_paths = get_image_paths(args.dir) | |
new_images = [] | |
mostCommon = collections.Counter(displayed).most_common() | |
for f in image_paths: | |
if f not in displayed: | |
new_images.append(f) | |
imgFile = random.choice(new_images) if new_images else random.choice(image_paths) | |
if displayed and imgFile not in displayed: | |
medianViewCount = mostCommon[int(len(mostCommon)/2)][1] | |
medianViewCount -= int(TICK * 2.0) | |
if medianViewCount < 0: | |
medianViewCount = 0 | |
for i in new_images: | |
displayed[i] = medianViewCount | |
return display_it(imgFile) | |
# normal case, pick from one of the most infrequently displayed images | |
leastDisplayedCount = collections.Counter(displayed).most_common()[-1][1] | |
display_it(random.choice([x for x in mostCommon if x[1] == leastDisplayedCount])[0]) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('dir', help='directory of images', nargs='?', default=os.getcwd()) | |
parser.add_argument('-debug', help='debug', action='store_true') | |
args = parser.parse_args() | |
image_paths = get_image_paths(args.dir) | |
if (args.debug): | |
TICK = 0.5 | |
while not image_paths: | |
time.sleep(3) | |
print("Waiting for images...") | |
image_paths = get_image_paths(args.dir) | |
window = pyglet.window.Window(fullscreen=False, width=640, height=420) if args.debug \ | |
else pyglet.window.Window(fullscreen=True) | |
@window.event | |
def on_draw(): | |
window.clear() | |
sprite.draw() | |
sprite = pyglet.sprite.Sprite(pyglet.image.load(random.choice(image_paths))) | |
display_it(random.choice(image_paths)) | |
pyglet.clock.schedule_interval(update_image, TICK) | |
pyglet.app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment