Last active
December 29, 2022 12:47
-
-
Save akent/b90cabb6e80fe5d36a734f3267c3cbc5 to your computer and use it in GitHub Desktop.
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