gifio – Access GIF-format images — Adafruit CircuitPython 1 documentation (original) (raw)

Adafruit CircuitPython

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:

__enter__() → GifWriter

No-op used by Context Managers.

__exit__() → None

Automatically deinitializes the hardware when exiting a context. SeeLifetime and ContextManagers for more info.

deinit() → None

Close the underlying file.

add_frame(bitmap: circuitpython_typing.ReadableBuffer, delay: float = 0.1) → None

Add a frame to the GIF.

Parameters:

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 uses Colorspace.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. ValueErrorwill be raised if the image is too wide. The height is not limited but images that are too large will cause a memory exception.

__enter__() → OnDiskGif

No-op used by Context Managers.

__exit__() → None

Automatically deinitializes the GIF when exiting a context. SeeLifetime and ContextManagers for more info.

width_: int_

Width of the gif. (read only)

height_: int_

Height of the gif. (read only)

bitmap_: displayio.Bitmap_

The bitmap used to hold the current frame.

palette_: displayio.Palette | None_

The palette for the current frame if it exists.

next_frame() → float

Loads the next frame. Returns expected delay before the next frame in seconds.

duration_: float_

Returns the total duration of the GIF in seconds. (read only)

frame_count_: int_

Returns the number of frames in the GIF. (read only)

min_delay_: float_

The minimum delay found between frames. (read only)

max_delay_: float_

The maximum delay found between frames. (read only)

deinit() → None

Release resources allocated by OnDiskGif.