The Adafruit PyPortal with a 320x240 pixel display makes a great GIF-playing platform with its snappy SAMD51 M4 processor.
Download the Project Bundle
The example uses a code file and a sample animated GIF image. To get everything you need, click on the Download Project Bundle link below, and uncompress the .zip file.
Connect a PyPortal to your computer via a known good USB data+power cable. It should show up as a thumb drive named CIRCUITPY.
Using File Explorer/Finder (depending on your Operating System), drag the contents of the unzipped bundle directory onto your board's CIRCUITPY drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.
The code below displays a single GIF image. To run it, copy one of the GIF images to the name sample.gif. Copy the file code-single-pyportal-displayio.py to code.py.
# SPDX-FileCopyrightText: 2023 Anne Barela for Adafruit Industries # # SPDX-License-Identifier: MIT # # gifio demo for the Adafruit PyPortal - single file # # Documentation: # https://docs.circuitpython.org/en/latest/shared-bindings/gifio/ # Updated 4/5/2023 # import time import gc import board import gifio import displayio import adafruit_touchscreen display = board.DISPLAY splash = displayio.Group() display.root_group = splash # Pyportal has a touchscreen, a touch stops the display WIDTH = board.DISPLAY.width HEIGHT = board.DISPLAY.height ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR, board.TOUCH_YD, board.TOUCH_YU, calibration=((5200, 59000), (5800, 57000)), size=(WIDTH, HEIGHT)) odg = gifio.OnDiskGif('/sample.gif') start = time.monotonic() next_delay = odg.next_frame() # Load the first frame end = time.monotonic() call_delay = end - start # Depending on your display the next line may need Colorspace.RGB565 # instead of Colorspace.RGB565_SWAPPED face = displayio.TileGrid(odg.bitmap, pixel_shader=displayio.ColorConverter (input_colorspace=displayio.Colorspace.RGB565_SWAPPED)) splash.append(face) board.DISPLAY.refresh() # Play the GIF file until screen is touched while True: time.sleep(max(0, next_delay - call_delay)) next_delay = odg.next_frame() if ts.touch_point is not None: break # End while # Clean up memory odg.deinit() odg = None gc.collect()
How It Works
First the code imports all the libraries needed for the example. Only the Adafruit_Touchscreen
library needs an external file, the rest are included inside CircuitPython. Ensure adafruit_touchscreen.mpy is in the /lib folder. Using displayio
, the CircuitPython display library, the screen is defined (the parameters are in the PyPortal definition file so they don't need to be looked up, things like the screen width 320 px and height 240 px).
To signal user input, the touchscreen is used. This isn't necessary in most applications but having a convenient input method can be handy, especially if the PyPortal is in a case.
The file sample.gif is opened via gifio
. You may get an error that sample.gif is not found, please copy one of the example GIF files to sample.gif.
The first frame is loaded using odg.next_frame()
. The time it takes to call the function is noted to make an adjustment for the time between frames later.
A displayio
TileGrid
is made consisting of the first frame and the entire display.
Finally there is a loop which constantly fetches frames and displays them with a file-defined pause between frames. As calling the next_frame
takes time (measured earlier), that time is subtracted from the frame rate specified in the file.
If the screen is touched, the memory is cleaned up and the program ends.
Text editor powered by tinymce.