gifio – Access GIF-format images

Available on these boards
  • 0xCB Helios
  • 42. Keebs Frood
  • ARAMCON Badge 2019
  • ARAMCON2 Badge
  • ATMegaZero ESP32-S2
  • Adafruit CLUE nRF52840 Express
  • Adafruit Camera
  • Adafruit Circuit Playground Bluefruit
  • Adafruit Feather Bluefruit Sense
  • Adafruit Feather ESP32 V2
  • Adafruit Feather ESP32-S2 Reverse TFT
  • Adafruit Feather ESP32-S2 TFT
  • Adafruit Feather ESP32S2
  • Adafruit Feather M4 CAN
  • Adafruit Feather M4 Express
  • Adafruit Feather MIMXRT1011
  • Adafruit Feather RP2040
  • Adafruit Feather RP2040 CAN
  • Adafruit Feather RP2040 DVI
  • Adafruit Feather RP2040 Prop-Maker
  • Adafruit Feather RP2040 RFM
  • Adafruit Feather RP2040 Scorpio
  • Adafruit Feather RP2040 ThinkInk
  • Adafruit Feather RP2040 USB Host
  • Adafruit Feather STM32F405 Express
  • Adafruit Feather nRF52840 Express
  • Adafruit Grand Central M4 Express
  • Adafruit Hallowing M4 Express
  • Adafruit ItsyBitsy M4 Express
  • Adafruit ItsyBitsy RP2040
  • Adafruit ItsyBitsy nRF52840 Express
  • Adafruit KB2040
  • Adafruit LED Glasses Driver nRF52840
  • Adafruit Macropad RP2040
  • Adafruit Matrix Portal M4
  • Adafruit Metro ESP32S2
  • Adafruit Metro M4 Airlift Lite
  • Adafruit Metro M4 Express
  • Adafruit Metro nRF52840 Express
  • Adafruit Monster M4SK
  • Adafruit PyPortal
  • Adafruit PyPortal Pynt
  • Adafruit PyPortal Titano
  • Adafruit QT Py ESP32 PICO
  • Adafruit QT Py ESP32S2
  • Adafruit QT Py RP2040
  • Adafruit QT2040 Trinkey
  • Adafruit Trellis M4 Express
  • AloriumTech Evo M51
  • Arduino Nano 33 BLE
  • Arduino Nano RP2040 Connect
  • Artisense Reference Design RD00
  • AtelierDuMaker nRF52840 Breakout
  • BBQ20KBD
  • BDMICRO VINA-D51
  • BLE-SS dev board Multi Sensor
  • BLOK
  • BPI-Bit-S2
  • BPI-Leaf-S3
  • BPI-PicoW-S3
  • BastBLE
  • BlueMicro840
  • COSMO-Pico
  • CP32-M4
  • Challenger NB RP2040 WiFi
  • Challenger RP2040 LTE
  • Challenger RP2040 LoRa
  • Challenger RP2040 SD/RTC
  • Challenger RP2040 SubGHz
  • Challenger RP2040 WiFi
  • Challenger RP2040 WiFi/BLE
  • CircuitBrains Deluxe
  • CrumpS2
  • Cytron Maker Feather AIoT S3
  • Cytron Maker Nano RP2040
  • Cytron Maker Pi RP2040
  • Deneyap Kart
  • Deneyap Kart 1A
  • Deneyap Mini v2
  • Diodes Delight Piunora
  • DynOSSAT-EDU-OBC
  • E-Fidget
  • ELECFREAKS PICO:ED
  • ESP 12k NodeMCU
  • ESP32-S2-DevKitC-1-N4R2
  • ESP32-S2-DevKitC-1-N8R2
  • ESP32-S3-DevKitC-1-N32R8
  • ESP32-S3-DevKitC-1-N8R2
  • ESP32-S3-DevKitC-1-N8R8
  • ESP32-S3-EYE
  • Electrolama minik
  • Electronut Labs Blip
  • Electronut Labs Papyr
  • EncoderPad RP2040
  • Espressif ESP32-EYE
  • Espruino Bangle.js 2
  • Espruino Wifi
  • Feather MIMXRT1011
  • Feather MIMXRT1062
  • FeatherS2
  • FeatherS2 Neo
  • FeatherS2 PreRelease
  • FeatherS3
  • Fig Pi
  • Franzininho WIFI w/Wrover
  • Gravitech Cucumber R
  • Gravitech Cucumber RS
  • HMI-DevKit-1.1
  • Hack Club Sprig
  • Hardkernel Odroid Go
  • HexKyS2
  • HiiBot BlueFi
  • IMXRT1010-EVK
  • IMXRT1015-EVK
  • IkigaiSense Vita nRF52840
  • IoTs2
  • Kaluga 1
  • LILYGO T-DISPLAY
  • LILYGO TEMBED ESP32S3
  • LILYGO TTGO T8 ESP32-S2
  • LILYGO TTGO T8 ESP32-S2 w/Display
  • Lilygo T-watch 2020 V3
  • M5Stack Core2
  • M5Stack Timer Camera X
  • MDBT50Q-DB-40
  • MDBT50Q-RX Dongle
  • MakerDiary nRF52840 MDK
  • MakerDiary nRF52840 MDK USB Dongle
  • Makerdiary M60 Keyboard
  • Makerdiary Pitaya Go
  • Makerdiary nRF52840 M.2 Developer Kit
  • Melopero Shake RP2040
  • Metro MIMXRT1011
  • MicroDev microS2
  • Mini SAM M4
  • NUCLEO STM32F746
  • NUCLEO STM32F767
  • NUCLEO STM32H743
  • Neuron
  • OPENMV-H7 R1
  • Oak Dev Tech BREAD2040
  • Oak Dev Tech Cast-Away RP2040
  • Oak Dev Tech PixelWing ESP32S2
  • Open Hardware Summit 2020 Badge
  • PCA10056 nRF52840-DK
  • PCA10059 nRF52840 Dongle
  • PYB LR Nano V2
  • Particle Argon
  • Particle Boron
  • Particle Xenon
  • PillBug
  • Pimoroni Badger 2040
  • Pimoroni Badger 2040 W
  • Pimoroni Inky Frame 5.7
  • Pimoroni Interstate 75
  • Pimoroni Keybow 2040
  • Pimoroni Motor 2040
  • Pimoroni PGA2040
  • Pimoroni Pico LiPo (16MB)
  • Pimoroni Pico LiPo (4MB)
  • Pimoroni Pico dv Base
  • Pimoroni PicoSystem
  • Pimoroni Plasma 2040
  • Pimoroni Plasma 2040W
  • Pimoroni Servo 2040
  • Pimoroni Tiny 2040 (2MB)
  • Pimoroni Tiny 2040 (8MB)
  • ProS3
  • PyKey 18 Numpad
  • PyKey 44 Ergo
  • PyKey 60
  • PyKey 87 TKL
  • PyboardV1_1
  • RP2.65-F
  • RP2040 Stamp
  • Raspberry Pi 4B
  • Raspberry Pi Compute Module 4
  • Raspberry Pi Compute Module 4 IO Board
  • Raspberry Pi Pico
  • Raspberry Pi Pico W
  • Raspberry Pi Zero
  • Raspberry Pi Zero 2W
  • Raspberry Pi Zero W
  • S2Mini
  • S2Pico
  • SAM E54 Xplained Pro
  • SAM32v26
  • SSCI ISP1807 Dev Board
  • SSCI ISP1807 Micro Board
  • ST STM32F746G Discovery
  • STM32F411E_DISCO
  • STM32F412G_DISCO
  • STM32F4_DISCO
  • Saola 1 w/Wrover
  • Seeed XIAO nRF52840 Sense
  • Seeeduino Wio Terminal
  • Seeeduino XIAO RP2040
  • SiLabs xG24 Dev Kit
  • SiLabs xG24 Explorer Kit
  • Silicognition LLC M4-Shim
  • Silicognition LLC RP2040-Shim
  • SparkFun MicroMod RP2040 Processor
  • SparkFun MicroMod SAMD51 Processor
  • SparkFun MicroMod nRF52840 Processor
  • SparkFun Pro Micro RP2040
  • SparkFun Pro nRF52840 Mini
  • SparkFun STM32 MicroMod Processor
  • SparkFun Teensy MicroMod Processor
  • SparkFun Thing Plus - RP2040
  • SparkFun Thing Plus - SAMD51
  • SparkFun Thing Plus - STM32
  • Sparkfun Thing Plus MGM240P
  • Swan R5
  • TG-Boards' Datalore IP M4
  • TG-Watch
  • THUNDERPACK_v11
  • THUNDERPACK_v12
  • Targett Module Clip w/Wrover
  • Teensy 4.0
  • Teensy 4.1
  • Teknikio Bluebird
  • The Open Book Feather
  • TinkeringTech ScoutMakes Azul
  • TinyPICO
  • TinyPICO Nano
  • TinyS2
  • TinyS3
  • UARTLogger II
  • VCC-GND Studio YD RP2040
  • VCC-GND YD-ESP32-S3 (N16R8)
  • VCC-GND YD-ESP32-S3 (N8R8)
  • W5100S-EVB-Pico
  • W5500-EVB-Pico
  • WarmBit BluePixel nRF52840
  • Waveshare ESP32-S2-Pico
  • Waveshare ESP32-S2-Pico-LCD
  • Waveshare RP2040-LCD-0.96
  • Waveshare RP2040-LCD-1.28
  • Waveshare RP2040-Zero
  • WeAct Studio Pico
  • WeAct Studio Pico 16MB
  • iLabs Challenger 840
  • iMX RT 1020 EVK
  • iMX RT 1040 EVK
  • iMX RT 1050 EVKB
  • iMX RT 1060 EVK
  • iMX RT 1060 EVKB
  • nanoESP32-S2 w/Wrover
  • nice!nano
  • nullbits Bit-C PRO
  • stm32f411ce-blackpill
  • stm32f411ce-blackpill-with-flash
  • takayoshiotake Octave RP2040

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, and L8 (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.

__enter__() GifWriter

No-op used by Context Managers.

__exit__() None

Automatically deinitializes the hardware when exiting a context. See Lifetime 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:
  • 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 uses Colorspace.RGB565_SWAPPED.

Parameters:

file (file) – The name of the GIF file.

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.

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)

__enter__() OnDiskGif

No-op used by Context Managers.

__exit__() None

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

next_frame() float

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

deinit() None

Release resources allocated by OnDiskGif.