forked from BluBean/pimoroni-Inky-Impression-57-image-frame
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.py
158 lines (128 loc) · 5.12 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env python3
import os
import glob
import sys
import time
import image_processor
from random import randrange
import signal
import RPi.GPIO as GPIO
import textwrap
from inky import Inky7Colour as Inky
#from inky.mock import InkyMockImpression as Inky # Simulator
try:
from PIL import Image, ImageDraw, ImageFont
except ImportError:
print("""This script requires PIL/Pillow, try:
sudo apt install python3-pil
""")
print("""
Inky Impression Slideshow. Display images from a folder on the E-Ink.
Usage: {file} /path/to/images
""")
# minimum time in seconds before the image changes
MIN_SLEEP_BETWEEN_IMAGES = 60
# extensions to load
EXTENSIONS = ('*.png', '*.jpg')
# Gpio pins for each button (from top to bottom)
BUTTONS = [5, 6, 16, 24]
# Set up RPi.GPIO with the "BCM" numbering scheme
GPIO.setmode(GPIO.BCM)
# Buttons connect to ground when pressed, so we should set them up
# with a "PULL UP", which weakly pulls the input signal to 3.3V.
GPIO.setup(BUTTONS, GPIO.IN, pull_up_down=GPIO.PUD_UP)
inky = Inky()
class ImageFrame:
images = []
current_image_index = 0
path_to_images = ''
imPro = None
# Not a lock since this is single threaded and we want to bypass, not wait
ignore_image_change = False
def __init__(self, path_to_images):
self.imPro = image_processor.ImageProcessor()
self.path_to_images = path_to_images
self.init_files()
self.add_buttons()
def init_files(self):
for extension in EXTENSIONS:
self.images.extend(glob.glob("%s/**/%s" % (self.path_to_images, extension), recursive=True))
if len(self.images) == 0:
error_message = "Error: folder \"%s\" contains no images" % self.images
self.display_error_message(error_message)
exit(1)
def display_next_image(self):
next_image_index = self.current_image_index + 1
if next_image_index >= len(self.images):
next_image_index = 0
self.display_image_by_index(next_image_index)
def display_previous_image(self):
prev_image_index = self.current_image_index - 1
if prev_image_index < 0:
prev_image_index = len(self.images) - 1
self.display_image_by_index(prev_image_index)
def display_error_message(self, error_text, text_color=(0, 0, 0), text_start_height=40):
image_message = Image.new("RGB", inky.resolution, color=(200, 0, 0))
font = ImageFont.load_default()
self.draw_multiple_line_text(image_message, error_text, font, text_color, text_start_height)
try:
inky.set_image(image_message, 1)
inky.show()
except BaseException as err:
error_text = f"Unexpected {err=}, {type(err)=}"
print(error_text)
def display_image_by_index(self, number):
if self.ignore_image_change:
print('Already changing image... request ignored')
return
try:
self.ignore_image_change = True
print('Opening and resizing image ', self.images[number])
image = Image.open(self.images[number])
resizedimage = image.resize(inky.resolution)
print('Diffusing image ', self.images[number])
self.imPro.diffuse_image(resizedimage)
print('Displaying image ', self.images[number])
inky.set_image(resizedimage, 1)
inky.set_border(inky.BLACK)
inky.show()
ignore_image_change = False
except BaseException as err:
error_text = f"Unexpected {err=}, {type(err)=}"
self.display_error_message(error_text)
finally:
self.current_image_index = number
self.ignore_image_change = False
def display_random_image(self):
image_index_to_show = randrange(len(self.images))
self.display_image_by_index(image_index_to_show)
def draw_multiple_line_text(self, image, text, font, text_color, text_start_height):
draw = ImageDraw.Draw(image)
image_width, image_height = image.size
y_text = text_start_height
lines = textwrap.wrap(text, width=40)
for line in lines:
line_width, line_height = font.getsize(line)
draw.text(((image_width - line_width) / 2, y_text),
line, font=font, fill=text_color)
y_text += line_height
def add_buttons(self):
print('Adding button hooks')
for pin in BUTTONS:
GPIO.add_event_detect(pin, GPIO.FALLING, self.handle_button, bouncetime=5000)
def handle_button(self, pin):
last_button = BUTTONS.index(pin)
if last_button == 0:
imageFrame.display_random_image()
elif last_button == 1:
imageFrame.display_next_image()
elif last_button == 2:
imageFrame.display_previous_image()
elif last_button == 3:
subprocess.run("sudo shutdown --poweroff now", shell=True)
imageFrame = ImageFrame(sys.argv[1])
# start with a random image otherwise things get boring fast...!
imageFrame.display_random_image();
while True:
time.sleep(MIN_SLEEP_BETWEEN_IMAGES)
imageFrame.display_next_image()