Draw an image in Pinebook framebuffer with Pygame

Default featured post

Part of my tinkering with my Pinebook is to play around with framebuffer. The reason is I can manipulate the display directly without going through X11. This is less resource intensive and especially useful for ARM powered devices. In this article, I show you how to draw an image in Pinebook framebuffer with Pygame library using Python.

Background

A part of my framebuffer journey is to replace some of the X11 applications with the framebuffer counterparts. However, sometimes I want to avoid using third-party framebuffer applications. Because the hassle of setting them up is too much. So I decided to start writing those that are easy. This way I can learn as well. And if needed debug my own code is always better :-).

Additionally, I didn’t want to write my programs with C. Even though I love C by my heart, I didn’t want to create misery for myself. I wanted to have fun and enjoy writing some code. So I decided to use Python instead. Of course, the first step was to find a library that supports framebuffer. The de facto library is pygame. It supports X11, SDL, and framebuffer. This way, the apps I write can also work with X11 without any issue. It’s the best option out there even though its main purpose is for game development.

The last thing left was to define an app to rewrite. I started with the easiest one which is an image viewer. The objective was given an image path and be able to view it in framebuffer. Something as a replacement of fbi.

In the following section I show you how to do that.

Installing Pygame and its dependencies

The very first step is to ensure we have the environment ready. We start by installing pip3. We avoid using Python 2.7 as it is obsolete. To install pip3 on Debian based distributions we run apt install as follows,

$ sudo apt install python3-pip

Alternatively, you can have a look at this post on how to install pip3 using python3-setuptools.

Now we need to install pygame dependencies before installing it.

$ sudo apt install python-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev libsmpeg-dev python-numpy subversion libportmidi-dev ffmpeg libswscale-dev libavformat-dev libavcodec-dev libfreetype2-dev python3-dev

And after installing the huge collection dependencies, finally, we need to install pygame using pip3,

$ sudo pip3 install pygame

Everything should be ready. To test that write python3 in the terminal and write import pygame. You shouldn’t see any error. If you got an error, means something is not correct and you may see what is the issue with the help of Google.

Drawing an image in framebuffer with Pygame

As I described earlier Pygame is a Python library for game development which is capable of handling X11, SDL, and framebuffer environments. This means, what we code using Pygame without changing a single line of the code can run in all environments hassle free. In other words, during the development, we don’t need to switch to framebuffer back and forth to see whether the code works or not. We can run it in X11 and once done with the coding, test it in framebuffer as well.

Enough talking let’s get started.

First let’s start with a piece of code that opens a file with a hard coded path as follows (inspired by lollo‘s answer from Stack Overflow, here),

import pygame
import sys
import time

pygame.init() # initializing the pygame

size = (pygame.display.Info().current_w, pygame.display.Info().current_h) # putting display info in a tuple
black = 0, 0, 0 # black color as the background color to fill the rest of the display

screen = pygame.display.set_mode(size) # set the display size

img = pygame.image.load("flower.jpeg") # loading the image in the current directory
img_frame = img.get_rect() # preparing the image frame

screen.fill(black) # filling the screen initially with black
screen.blit(img, img_frame) # writing the image and the frame to the buffer
pygame.display.flip() # flip the switch to show the image

time.sleep(25) # wait for 25 seconds before image disappear

We can save the code in a file, let’s call it image_gimmick.py. Now we should be able to run the code python3 image_gimmick.py and should display an image as long as flower.jpeg file is available in the python code path.

Now to improve the code, we want to do the following adjustments to it:

  • Get the image path from the user
  • If the user presses ESC then close the image window

So our final code will look like this:

And that’s pretty much it. After that, we can run the program,

$ python3 image_gimmick.py ~/Desktop/nature.png

Keep in mind that this code is not the final version and base on given input it may throw some errors. It is just good as a base for this tutorial.