Skip to content

Commit 15fe750

Browse files
authored
Merge pull request #54 from makermelissa/master
Initial commit of PiTFT Animated Gif Player
2 parents b236966 + 495a268 commit 15fe750

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"""
2+
Example to extract the frames and other parameters from an animated gif
3+
and then run the animation on the display.
4+
5+
Usage:
6+
python3 rgb_display_pillow_animated_gif.py
7+
8+
This example is for use on (Linux) computers that are using CPython with
9+
Adafruit Blinka to support CircuitPython libraries. CircuitPython does
10+
not support PIL/pillow (python imaging library)!
11+
12+
Author(s): Melissa LeBlanc-Williams for Adafruit Industries
13+
"""
14+
import os
15+
import time
16+
import digitalio
17+
import board
18+
from PIL import Image
19+
import adafruit_rgb_display.ili9341 as ili9341
20+
import adafruit_rgb_display.st7789 as st7789 # pylint: disable=unused-import
21+
import adafruit_rgb_display.hx8357 as hx8357 # pylint: disable=unused-import
22+
import adafruit_rgb_display.st7735 as st7735 # pylint: disable=unused-import
23+
import adafruit_rgb_display.ssd1351 as ssd1351 # pylint: disable=unused-import
24+
import adafruit_rgb_display.ssd1331 as ssd1331 # pylint: disable=unused-import
25+
26+
# Configuration for CS and DC pins (these are PiTFT defaults):
27+
cs_pin = digitalio.DigitalInOut(board.CE0)
28+
dc_pin = digitalio.DigitalInOut(board.D25)
29+
reset_pin = digitalio.DigitalInOut(board.D24)
30+
31+
def init_button(pin):
32+
button = digitalio.DigitalInOut(pin)
33+
button.switch_to_input()
34+
button.pull = digitalio.Pull.UP
35+
return button
36+
37+
class AnimatedGif:
38+
def __init__(self, display, folder=None):
39+
self._frame_count = 0
40+
self._loop = 0
41+
self._index = 0
42+
self._delay = 0
43+
self._gif_files = []
44+
self._frames = []
45+
self.display = display
46+
self.advance_button = init_button(board.D17)
47+
self.back_button = init_button(board.D22)
48+
if folder is not None:
49+
self.load_files(folder)
50+
self.run()
51+
52+
def advance(self, loop=False):
53+
if self._index < len(self._gif_files) - 1:
54+
self._index += 1
55+
elif loop and self._index == len(self._gif_files) - 1:
56+
self._index = 0
57+
58+
def back(self, loop=False):
59+
if self._index > 0:
60+
self._index -= 1
61+
elif loop and self._index == 0:
62+
self._index = len(self._gif_files) - 1
63+
64+
def load_files(self, folder):
65+
self._gif_files = [f for f in os.listdir(folder) if f[-4:] == '.gif']
66+
print("Found", self._gif_files)
67+
if not self._gif_files:
68+
print("No Gif files found in current folder")
69+
exit()
70+
71+
def preload(self):
72+
image = Image.open(self._gif_files[self._index])
73+
print("Loading {}...".format(self._gif_files[self._index]))
74+
self._delay = image.info['duration']
75+
if "loop" in image.info:
76+
self._loop = image.info['loop']
77+
else:
78+
self._loop = 1
79+
self._frame_count = image.n_frames
80+
81+
for frame in range(self._frame_count):
82+
image.seek(frame)
83+
# Create blank image for drawing.
84+
# Make sure to create image with mode 'RGB' for full color.
85+
frame_image = Image.new('RGB', (width, height))
86+
frame_image.paste(image, (width // 2 - image.width // 2,
87+
height // 2 - image.height // 2))
88+
self._frames.append(frame_image)
89+
90+
def play(self):
91+
self.preload()
92+
93+
# Check if we have loaded any files first
94+
if not self._gif_files:
95+
print("There are no Gif Images to Play")
96+
97+
for frame_image in self._frames:
98+
self.display.image(frame_image)
99+
if not self.advance_button.value:
100+
self.advance()
101+
elif not self.back_button.value:
102+
self.back()
103+
time.sleep(self._delay / 1000)
104+
105+
if self._loop == 1:
106+
return
107+
if self._loop > 0:
108+
self._loop -= 1
109+
110+
def run(self):
111+
while True:
112+
self.play()
113+
self.advance(True)
114+
115+
# Config for display baudrate (default max is 24mhz):
116+
BAUDRATE = 64000000
117+
118+
# Setup SPI bus using hardware SPI:
119+
spi = board.SPI()
120+
121+
# pylint: disable=line-too-long
122+
# Create the display:
123+
#disp = st7789.ST7789(spi, rotation=90 # 2.0" ST7789
124+
#disp = st7789.ST7789(spi, height=240, y_offset=80, rotation=90 # 1.3", 1.54" ST7789
125+
#disp = st7789.ST7789(spi, rotation=90, width=135, height=240, x_offset=53, y_offset=40, # 1.14" ST7789
126+
#disp = hx8357.HX8357(spi, rotation=180, # 3.5" HX8357
127+
#disp = st7735.ST7735R(spi, rotation=90, # 1.8" ST7735R
128+
#disp = st7735.ST7735R(spi, rotation=270, height=128, x_offset=2, y_offset=3, # 1.44" ST7735R
129+
#disp = st7735.ST7735R(spi, rotation=90, bgr=True, # 0.96" MiniTFT ST7735R
130+
#disp = ssd1351.SSD1351(spi, rotation=180, # 1.5" SSD1351
131+
#disp = ssd1351.SSD1351(spi, height=96, y_offset=32, rotation=180, # 1.27" SSD1351
132+
#disp = ssd1331.SSD1331(spi, rotation=180, # 0.96" SSD1331
133+
disp = ili9341.ILI9341(spi, rotation=90, # 2.2", 2.4", 2.8", 3.2" ILI9341
134+
cs=cs_pin, dc=dc_pin, rst=reset_pin, baudrate=BAUDRATE)
135+
# pylint: enable=line-too-long
136+
137+
if disp.rotation % 180 == 90:
138+
height = disp.width # we swap height/width to rotate it to landscape!
139+
width = disp.height
140+
else:
141+
width = disp.width # we swap height/width to rotate it to landscape!
142+
height = disp.height
143+
144+
gif_player = AnimatedGif(disp, ".")

0 commit comments

Comments
 (0)