gifio
– Access GIF-format images
Available on these boards
- class gifio.GifWriter(file: BinaryIO | str, width: int, height: int, colorspace: displayio.Colorspace, loop: bool = True, dither: bool = False)
Construct a GifWriter object
- Parameters:
file – Either a file open in bytes mode, or the name of a file to open in bytes mode.
width – The width of the image. All frames must have the same width.
height – The height of the image. All frames must have the same height.
colorspace – The colorspace of the image. All frames must have the same colorspace. The supported colorspaces are
RGB565
,BGR565
,RGB565_SWAPPED
,BGR565_SWAPPED
, andL8
(greyscale)loop – If True, the GIF is marked for looping playback
dither – If True, and the image is in color, a simple ordered dither is applied.
- __exit__() None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for more info.
- add_frame(bitmap: circuitpython_typing.ReadableBuffer, delay: float = 0.1) None
Add a frame to the GIF.
- Parameters:
bitmap – The frame data
delay – The frame delay in seconds. The GIF format rounds this to the nearest 1/100 second, and the largest permitted value is 655 seconds.
- class gifio.OnDiskGif(file: str)
Loads one frame of a GIF into memory at a time.
The code can be used in cooperation with displayio but this mode is relatively slow:
import board import gifio import displayio import time display = board.DISPLAY splash = displayio.Group() display.root_group = splash odg = gifio.OnDiskGif('/sample.gif') start = time.monotonic() next_delay = odg.next_frame() # Load the first frame end = time.monotonic() overhead = end - start face = displayio.TileGrid( odg.bitmap, pixel_shader=displayio.ColorConverter( input_colorspace=displayio.Colorspace.RGB565_SWAPPED ), ) splash.append(face) board.DISPLAY.refresh() # Display repeatedly. while True: # Sleep for the frame delay specified by the GIF, # minus the overhead measured to advance between frames. time.sleep(max(0, next_delay - overhead)) next_delay = odg.next_frame()
The displayio Group and TileGrid layers can be bypassed and the image can be directly blitted to the full screen. This can give a speed-up of ~4x to ~6x depending on the GIF and display. This requires an LCD that uses standard codes to set the update area, and which accepts RGB565_SWAPPED pixel data directly:
# Initial set-up the same as above # Take over display to drive directly display.auto_refresh = False display_bus = display.bus # Display repeatedly & directly. while True: # Sleep for the frame delay specified by the GIF, # minus the overhead measured to advance between frames. time.sleep(max(0, next_delay - overhead)) next_delay = odg.next_frame() display_bus.send(42, struct.pack(">hh", 0, odg.bitmap.width - 1)) display_bus.send(43, struct.pack(">hh", 0, odg.bitmap.height - 1)) display_bus.send(44, odg.bitmap) # The following optional code will free the OnDiskGif and allocated resources # after use. This may be required before loading a new GIF in situations # where RAM is limited and the first GIF took most of the RAM. odg.deinit() odg = None gc.collect()
Create an
OnDiskGif
object with the given file. The GIF frames are decoded into RGB565 big-endian format.displayio
expects little-endian, so the example above usesColorspace.RGB565_SWAPPED
.- Parameters:
file (file) – The name of the GIF file.
If the image is too large it will be cropped at the bottom and right when displayed.
Limitations: The image width is limited to 320 pixels at present.
ValueError
will be raised if the image is too wide. The height is not limited but images that are too large will cause a memory exception.- __exit__() None
Automatically deinitializes the GIF when exiting a context. See Lifetime and ContextManagers for more info.
- bitmap: displayio.Bitmap
The bitmap used to hold the current frame.
- palette: displayio.Palette | None
The palette for the current frame if it exists.