From 50a3d6f29fc35d859420f83779c9f7e7da8636db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Wed, 15 Aug 2018 12:19:10 +0200 Subject: [PATCH] reformat --- broadcast.py | 6 +- photobox.py | 571 +++++++++++++++++++++++++-------------------------- 2 files changed, 278 insertions(+), 299 deletions(-) diff --git a/broadcast.py b/broadcast.py index a47f781..ca1204c 100755 --- a/broadcast.py +++ b/broadcast.py @@ -3,9 +3,9 @@ import json import socket -UDP_IP = "255.255.255.255" -UDP_PORT = 32145 -MESSAGE = {"subject": "Fotobox Broadcast", "port": 80} +UDP_IP = "255.255.255.255" +UDP_PORT = 32145 +MESSAGE = {"subject": "Fotobox Broadcast", "port": 80} sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/photobox.py b/photobox.py index 2218d73..03a10a0 100755 --- a/photobox.py +++ b/photobox.py @@ -1,125 +1,118 @@ #!/usr/bin/python -import sys, os, inspect -import pytz, datetime -from time import sleep -from PIL import Image -from shutil import copyfile +import datetime +import inspect +import os +import sys from math import floor -import RPi.GPIO as GPIO +from shutil import copyfile +from time import sleep +import RPi.GPIO as GPIO import picamera import pygame -import random -import time +from PIL import Image # ~ import server - - __all__ = ["monotonic_time"] import ctypes -CLOCK_MONOTONIC_RAW = 4 # see +CLOCK_MONOTONIC_RAW = 4 # see + class timespec(ctypes.Structure): - _fields_ = [ - ('tv_sec', ctypes.c_long), - ('tv_nsec', ctypes.c_long) - ] + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + librt = ctypes.CDLL('librt.so.1', use_errno=True) clock_gettime = librt.clock_gettime clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)] + def monotonic_time(): - t = timespec() - if clock_gettime(CLOCK_MONOTONIC_RAW , ctypes.pointer(t)) != 0: - errno_ = ctypes.get_errno() - raise OSError(errno_, os.strerror(errno_)) - return t.tv_sec + t.tv_nsec * 1e-9 - - + t = timespec() + if clock_gettime(CLOCK_MONOTONIC_RAW, ctypes.pointer(t)) != 0: + errno_ = ctypes.get_errno() + raise OSError(errno_, os.strerror(errno_)) + return t.tv_sec + t.tv_nsec * 1e-9 os.chdir(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) - # CONFIGURATION -WIDTH = 800 -HEIGHT = 480 -FONTSIZE = 500 -PIC_INTERVAL = 0.5 -TEXT_INTERVAL = 0.5 -TEXT_POS = (250, -40) -OVERLAY_ALPHA = 64 -COLOR_BACK = pygame.Color(0, 0, 0) -COLOR_FLASH = pygame.Color(255, 255, 255) -GRAPHICS_DIR = "graphics" -IMAGE_DIR = "images/0-CURRENT" -COUNTDOWN = 3 -SHOT_COUNT = 3 -BORDER = 10 +WIDTH = 800 +HEIGHT = 480 +FONTSIZE = 500 +PIC_INTERVAL = 0.5 +TEXT_INTERVAL = 0.5 +TEXT_POS = (250, -40) +OVERLAY_ALPHA = 64 +COLOR_BACK = pygame.Color(0, 0, 0) +COLOR_FLASH = pygame.Color(255, 255, 255) +GRAPHICS_DIR = "graphics" +IMAGE_DIR = "images/0-CURRENT" +COUNTDOWN = 3 +SHOT_COUNT = 3 +BORDER = 10 -GPIO_LED_BORDER = 7 -GPIO_SPOT_RIGHT = 35 -GPIO_SPOT_LEFT = 37 -GPIO_BUTTON_LED = 36 -GPIO_BUTTON = 38 - -THUMB_WIDTH = int((800 - BORDER) / SHOT_COUNT - BORDER) -THUMB_HEIGHT = int(THUMB_WIDTH / 1.333) - -IMAGES_ORIGINAL = os.path.join(IMAGE_DIR, "original") -IMAGES_TODO = os.path.join(IMAGE_DIR, "todo") +GPIO_LED_BORDER = 7 +GPIO_SPOT_RIGHT = 35 +GPIO_SPOT_LEFT = 37 +GPIO_BUTTON_LED = 36 +GPIO_BUTTON = 38 +THUMB_WIDTH = int((800 - BORDER) / SHOT_COUNT - BORDER) +THUMB_HEIGHT = int(THUMB_WIDTH / 1.333) +IMAGES_ORIGINAL = os.path.join(IMAGE_DIR, "original") +IMAGES_TODO = os.path.join(IMAGE_DIR, "todo") # global variables -spot_mode = 0 -session_start = monotonic_time() - +spot_mode = 0 +session_start = monotonic_time() # GPIO helpers def led_border(state): - global GPIO_LED_BORDER - GPIO.output(GPIO_LED_BORDER, state) + global GPIO_LED_BORDER + GPIO.output(GPIO_LED_BORDER, state) def set_spot_mode(new_mode): - global spot_mode - spot_mode = new_mode % 4 - GPIO.output(GPIO_SPOT_LEFT, not (spot_mode & 1)) - GPIO.output(GPIO_SPOT_RIGHT, not (spot_mode & 2)) + global spot_mode + spot_mode = new_mode % 4 + GPIO.output(GPIO_SPOT_LEFT, not (spot_mode & 1)) + GPIO.output(GPIO_SPOT_RIGHT, not (spot_mode & 2)) def next_spot_mode(): - global spot_mode - set_spot_mode(spot_mode + 1) - + global spot_mode + set_spot_mode(spot_mode + 1) # user interface def button_press(gpio_id): - next_spot_mode() - + next_spot_mode() # INIT GPIO GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) -GPIO.setup(GPIO_SPOT_RIGHT, GPIO.OUT, initial=GPIO.HIGH) -GPIO.setup(GPIO_SPOT_LEFT, GPIO.OUT, initial=GPIO.HIGH) -GPIO.setup(GPIO_LED_BORDER, GPIO.OUT, initial=GPIO.LOW) -GPIO.setup(GPIO_BUTTON_LED, GPIO.OUT, initial=GPIO.LOW) +GPIO.setup(GPIO_SPOT_RIGHT, GPIO.OUT, initial=GPIO.HIGH) +GPIO.setup(GPIO_SPOT_LEFT, GPIO.OUT, initial=GPIO.HIGH) +GPIO.setup(GPIO_LED_BORDER, GPIO.OUT, initial=GPIO.LOW) +GPIO.setup(GPIO_BUTTON_LED, GPIO.OUT, initial=GPIO.LOW) -GPIO.setup(GPIO_BUTTON, GPIO.IN) +GPIO.setup(GPIO_BUTTON, GPIO.IN) GPIO.add_event_detect(GPIO_BUTTON, GPIO.FALLING, button_press, bouncetime=300) led_border(False) @@ -136,26 +129,24 @@ led_border(True) sleep(0.02) led_border(False) - - # INIT PYGAME pygame.init() pygame.mouse.set_visible(False) -screen = pygame.display.set_mode((WIDTH,HEIGHT)) - - +screen = pygame.display.set_mode((WIDTH, HEIGHT)) # LOAD GRAPHICS gfx = {} + def _load(name): - filename = "%s.png" % name - path = os.path.join(GRAPHICS_DIR, filename) - - img = pygame.image.load(path) - rect = img.get_rect() - - gfx[name] = (img, rect) + filename = "%s.png" % name + path = os.path.join(GRAPHICS_DIR, filename) + + img = pygame.image.load(path) + rect = img.get_rect() + + gfx[name] = (img, rect) + _load("begin") _load("loading") @@ -166,261 +157,249 @@ _load("end_no") _load("saved") _load("canceled") - - # LOAD COUNTDOWN OVERLAYS img_cdn = [] pad_cdn = [] for i in range(0, COUNTDOWN): - filename = "%s.png" % (COUNTDOWN - i) - path = os.path.join(GRAPHICS_DIR, filename) - - img = Image.open(path) - pad = Image.new('RGB', ( - ((img.size[0] + 31) // 32) * 32, - ((img.size[1] + 15) // 16) * 16, - )) - pad.paste(img, (0, 0)) - img_cdn.append(img) - pad_cdn.append(pad) + filename = "%s.png" % (COUNTDOWN - i) + path = os.path.join(GRAPHICS_DIR, filename) + img = Image.open(path) + pad = Image.new('RGB', ( + ((img.size[0] + 31) // 32) * 32, + ((img.size[1] + 15) // 16) * 16, + )) + pad.paste(img, (0, 0)) + img_cdn.append(img) + pad_cdn.append(pad) # FUNCTIONS ======================================================================================== def waitForEvent(): - pygame.event.clear() - while 1: - sleep(0.25) - - events = pygame.event.get() - if len(events) > 0: - for event in events: - if event.type == pygame.QUIT: - sys.exit(0) - return events + pygame.event.clear() + while 1: + sleep(0.25) + events = pygame.event.get() + if len(events) > 0: + for event in events: + if event.type == pygame.QUIT: + sys.exit(0) + return events def waitForTouch(): - pos = (-1, -1) - while True: - events = waitForEvent() - for event in events: - if event.type == pygame.MOUSEMOTION: - pos = event.pos - elif event.type == pygame.MOUSEBUTTONUP: - return pos - + pos = (-1, -1) + while True: + events = waitForEvent() + for event in events: + if event.type == pygame.MOUSEMOTION: + pos = event.pos + elif event.type == pygame.MOUSEBUTTONUP: + return pos def maintainance(): - screen.fill(COLOR_BACK) - screen.blit(maintain, maintain_rect) - pygame.display.flip() - - # wait - pos = waitForTouch() + screen.fill(COLOR_BACK) + screen.blit(maintain, maintain_rect) + pygame.display.flip() + # wait + pos = waitForTouch() def waitForBegin(): - screen.fill(COLOR_BACK) - screen.blit(*gfx["begin"]) - pygame.display.flip() - - # wait - pos = waitForTouch() - if pos[0] > 720 and pos[1] > 400: - maintainance() + screen.fill(COLOR_BACK) + screen.blit(*gfx["begin"]) + pygame.display.flip() + # wait + pos = waitForTouch() + if pos[0] > 720 and pos[1] > 400: + maintainance() def countdown(camera, pad, img): - sleep(PIC_INTERVAL) - o = camera.add_overlay(pad.tostring(), size=img.size) - o.alpha = OVERLAY_ALPHA - o.layer = 3 - sleep(TEXT_INTERVAL) - camera.remove_overlay(o) - + sleep(PIC_INTERVAL) + o = camera.add_overlay(pad.tostring(), size=img.size) + o.alpha = OVERLAY_ALPHA + o.layer = 3 + sleep(TEXT_INTERVAL) + camera.remove_overlay(o) def makePhotos(): - # CLEAR SCREEN - screen.fill(COLOR_BACK) - pygame.display.update() - - # INIT CAMERA - camera = picamera.PiCamera() - camera.vflip = False - camera.hflip = True - camera.resolution = (2592, 1944) - camera.rotation = 90 - camera.start_preview() - - # COUNTDOWN - led_border(True) - for i in range(0, COUNTDOWN): - countdown(camera, pad_cdn[i], img_cdn[i]) - led_border(False) - - # SHOTS - for i in range(0, SHOT_COUNT): - # SHOT! - sleep(PIC_INTERVAL) - led_border(True) - camera.capture("./tmp%s.jpg" % i, format='jpeg', quality=100, thumbnail=None) - led_border(False) - - # PAUSE - if i < SHOT_COUNT - 1: - screen.fill(COLOR_BACK) - pygame.display.update() - camera.start_preview() - sleep(TEXT_INTERVAL) - - # CLOSE CAMERA - camera.close() + # CLEAR SCREEN + screen.fill(COLOR_BACK) + pygame.display.update() + # INIT CAMERA + camera = picamera.PiCamera() + camera.vflip = False + camera.hflip = True + camera.resolution = (2592, 1944) + camera.rotation = 90 + camera.start_preview() + + # COUNTDOWN + led_border(True) + for i in range(0, COUNTDOWN): + countdown(camera, pad_cdn[i], img_cdn[i]) + led_border(False) + + # SHOTS + for i in range(0, SHOT_COUNT): + # SHOT! + sleep(PIC_INTERVAL) + led_border(True) + camera.capture("./tmp%s.jpg" % i, format='jpeg', quality=100, thumbnail=None) + led_border(False) + + # PAUSE + if i < SHOT_COUNT - 1: + screen.fill(COLOR_BACK) + pygame.display.update() + camera.start_preview() + sleep(TEXT_INTERVAL) + + # CLOSE CAMERA + camera.close() def chooseImages(): - # clear screen - screen.fill(COLOR_BACK) - screen.blit(*gfx["loading"]) - pygame.display.update() - - # load images from disk - img_tmp = [] - rect_tmp = [] - choices = [] - x = 12 - for i in range(0, SHOT_COUNT): - img = pygame.image.load("tmp%s.jpg" % i) - img = pygame.transform.scale(img, (THUMB_WIDTH, THUMB_HEIGHT)) - rect = img.get_rect() - rect.x = x - rect.y = 146 - - img_tmp.append(img) - rect_tmp.append(rect) - choices.append(0) - - x = x + THUMB_WIDTH + BORDER - - - save = False - cancel = False - any_choice = False - while not cancel and (not save or not any_choice): - # reset save (if nothing selected) - save = False - - # draw background - screen.fill(COLOR_BACK) - if any_choice: - screen.blit(*gfx["end_yes"]) - else: - screen.blit(*gfx["end_no"]) - - # draw images - for i in range(0, SHOT_COUNT): - screen.blit(img_tmp[i], rect_tmp[i]) - - # draw choices - x = 12 - for choice in choices: - if choice > 0: - (img, rect) = gfx["yes"] - else: - (img, rect) = gfx["no"] - - rect.x = x + (THUMB_WIDTH - rect.width) / 2 - rect.y = 340 - screen.blit(img, rect) - - x = x + THUMB_WIDTH + BORDER - - # update display - pygame.display.flip() - - # wait for new event (touch screen / mouse / keyboard) - pos = waitForTouch() - if pos[1] > 140: - # toggle image - i = int(floor((pos[0] - BORDER / 2) / (THUMB_WIDTH + BORDER))) - if i >= 0 and i < SHOT_COUNT: - choices[i] = (choices[i] + 1) % 2 - - elif pos[1] < 100: - # top menu buttons - if pos[0] > 0 and pos[0] < 266: - cancel = True - elif pos[0] > 533 and pos[0] < 800 and (choices[0] > 0 or choices[1] > 0 or choices[2] > 0): - save = True - - any_choice = False - for choice in choices: - if choice > 0: - any_choice = True - break - - return (choices, save) - + # clear screen + screen.fill(COLOR_BACK) + screen.blit(*gfx["loading"]) + pygame.display.update() + + # load images from disk + img_tmp = [] + rect_tmp = [] + choices = [] + x = 12 + for i in range(0, SHOT_COUNT): + img = pygame.image.load("tmp%s.jpg" % i) + img = pygame.transform.scale(img, (THUMB_WIDTH, THUMB_HEIGHT)) + rect = img.get_rect() + rect.x = x + rect.y = 146 + + img_tmp.append(img) + rect_tmp.append(rect) + choices.append(0) + + x = x + THUMB_WIDTH + BORDER + + save = False + cancel = False + any_choice = False + while not cancel and (not save or not any_choice): + # reset save (if nothing selected) + save = False + + # draw background + screen.fill(COLOR_BACK) + if any_choice: + screen.blit(*gfx["end_yes"]) + else: + screen.blit(*gfx["end_no"]) + + # draw images + for i in range(0, SHOT_COUNT): + screen.blit(img_tmp[i], rect_tmp[i]) + + # draw choices + x = 12 + for choice in choices: + if choice > 0: + (img, rect) = gfx["yes"] + else: + (img, rect) = gfx["no"] + + rect.x = x + (THUMB_WIDTH - rect.width) / 2 + rect.y = 340 + screen.blit(img, rect) + + x = x + THUMB_WIDTH + BORDER + + # update display + pygame.display.flip() + + # wait for new event (touch screen / mouse / keyboard) + pos = waitForTouch() + if pos[1] > 140: + # toggle image + i = int(floor((pos[0] - BORDER / 2) / (THUMB_WIDTH + BORDER))) + if i >= 0 and i < SHOT_COUNT: + choices[i] = (choices[i] + 1) % 2 + + elif pos[1] < 100: + # top menu buttons + if pos[0] > 0 and pos[0] < 266: + cancel = True + elif pos[0] > 533 and pos[0] < 800 and (choices[0] > 0 or choices[1] > 0 or choices[2] > 0): + save = True + + any_choice = False + for choice in choices: + if choice > 0: + any_choice = True + break + + return (choices, save) def saveImages(choices): - local = datetime.datetime.now() - session_age = (monotonic_time() - session_start) - - try: - os.makedirs(IMAGES_ORIGINAL) - except OSError: - pass - - try: - os.makedirs(IMAGES_TODO) - except OSError: - pass - - print("saving images...") - for i in range(0, SHOT_COUNT): - if choices[i] > 0: - print(" saving image #%s" % i) - - filename = "%s-%s-session_age=%05d.jpg" % (local.strftime("%Y%m%dT%H:%M:%S.%f%z"), i, session_age) - - path_tmp = "tmp%s.jpg" % i - path_original = os.path.join(IMAGES_ORIGINAL, filename) - path_todo = os.path.join(IMAGES_TODO, filename) - - os.rename(path_tmp, path_original) - copyfile(path_original, path_todo) + local = datetime.datetime.now() + session_age = (monotonic_time() - session_start) + try: + os.makedirs(IMAGES_ORIGINAL) + except OSError: + pass + + try: + os.makedirs(IMAGES_TODO) + except OSError: + pass + + print("saving images...") + for i in range(0, SHOT_COUNT): + if choices[i] > 0: + print(" saving image #%s" % i) + + filename = "%s-%s-session_age=%05d.jpg" % (local.strftime("%Y%m%dT%H:%M:%S.%f%z"), i, session_age) + + path_tmp = "tmp%s.jpg" % i + path_original = os.path.join(IMAGES_ORIGINAL, filename) + path_todo = os.path.join(IMAGES_TODO, filename) + + os.rename(path_tmp, path_original) + copyfile(path_original, path_todo) try: - while 1: - waitForBegin() - - makePhotos() - (choices, save) = chooseImages() - if save: - saveImages(choices); - screen.fill(COLOR_BACK) - screen.blit(*gfx["saved"]) - pygame.display.flip() - else: - screen.fill(COLOR_BACK) - screen.blit(*gfx["canceled"]) - pygame.display.flip() - - sleep(2) - + while 1: + waitForBegin() + + makePhotos() + (choices, save) = chooseImages() + if save: + saveImages(choices); + screen.fill(COLOR_BACK) + screen.blit(*gfx["saved"]) + pygame.display.flip() + else: + screen.fill(COLOR_BACK) + screen.blit(*gfx["canceled"]) + pygame.display.flip() + + sleep(2) + except KeyboardInterrupt: - print("") - + print("") + finally: - led_border(False) - pygame.quit() + led_border(False) + pygame.quit()