If you are using CPython on Linux, you can also make use of the Pillow library and the image function to draw images to the display. The only limitations are the image needs to be the exact same size as the Framebuffer and needs to be in RGB mode.

We're going to go over an example for running this. First download the blinka_16x16.png image and upload it to the folder that you plan to run the script in.

Next download the pixel_framebuf_pillow_image.py example, which is available in the Library repo:

# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams, written for Adafruit Industries
# SPDX-License-Identifier: MIT
"""
Be sure to check the learn guides for more usage information.

This example is for use on (Linux) computers that are using CPython with
Adafruit Blinka to support CircuitPython libraries. CircuitPython does
not support PIL/pillow (python imaging library)!

Author(s): Melissa LeBlanc-Williams for Adafruit Industries
"""
import board
import neopixel
from PIL import Image
from adafruit_pixel_framebuf import PixelFramebuffer

pixel_pin = board.D18
pixel_width = 16
pixel_height = 16

pixels = neopixel.NeoPixel(
    pixel_pin, pixel_width * pixel_height, brightness=0.1, auto_write=False,
)

pixel_framebuf = PixelFramebuffer(pixels, pixel_width, pixel_height, reverse_x=True,)

# Make a black background in RGBA Mode
image = Image.new("RGBA", (pixel_width, pixel_height))

# Open the icon
icon = Image.open("blinka_16x16.png")

# Alpha blend the icon onto the background
image.alpha_composite(icon)

# Convert the image to RGB and display it
pixel_framebuf.image(image.convert("RGB"))
pixel_framebuf.display()

Run the code.

  • sudo python3 pixel_framebuf_pillow_image.py

You should see an output similar to below:

How It Works

Below describes what is going on. You may recognize much of it from the previous section.

First start with imports. In addition to the usual imports, also import Image from the Pillow library.

Download: file
import board
import neopixel
from PIL import Image
from adafruit_pixel_framebuf import PixelFramebuffer

After that, set up the object, except it's using D18 in this case. You can find more details about this earlier in this guide.

Download: file
pixel_pin = board.D18
pixel_width = 16
pixel_height = 16

pixels = neopixel.NeoPixel(
    pixel_pin, pixel_width * pixel_height, brightness=0.1, auto_write=False,
)

pixel_framebuf = PixelFramebuffer(pixels, pixel_width, pixel_height, reverse_x=True,)

Next use Pillow to create a background and alpha_composite() the image onto it. The reason to do it this way is because the adafruit_framebuf library requires the image to be in RGB format and if you directly you use convert() in Pillow, it will convert all transparencies to white. It's easier to see with a darker background.

Start off by creating a new image in RGBA mode. RGBA mode is required to use the alpha_composite() function. The default color is black, so you don't need to specify a color to use by default, although you certainly could.

Download: file
image = Image.new("RGBA", (pixel_width, pixel_height))

Next open the icon file.

Download: file
icon = Image.open("blinka_16x16.png")

Next use the alpha_composite() function to blend the icon onto the black background.

Download: file
image.alpha_composite(icon)

Finally, convert the combined image to RGB right before passing it to the image() function and then display it.

Download: file
pixel_framebuf.image(image.convert("RGB"))
pixel_framebuf.display()

That's it. It should display onto the NeoPixels.

This guide was first published on Sep 22, 2020. It was last updated on Sep 22, 2020.

This page (Image Drawing with Python) was last updated on Nov 06, 2020.