Display a PNG Image on small 128×128 OLED LCD

Now that my small OLED display automatically loads the device drivers on boot, it was time to see if I could display an image on my new frame buffer device.

To start with I went looking for a very basic graphics library that would allow me to experiment on frame buffer devices. There is certainly no shortage of libraries to choose from. The library that I settled on was the “Lightweight C 2D graphics API agnostic library with parallelism support” written by grz0zrg. It had both PNG and JPG routines that could output to a simple frame buffer device, being written in C was also a winner.

Flicking through the various examples the quickstart.c file seemed to have nearly everything I needed to display a PNG file on my OLED. Not so long ago a fellow AREG club member shot me some icon files for our club website; one of these icons was 512×512 pixels in size which made it an excellent candidate for shrinking to 128×128 pixels and using it on my OLED.

Downloading the library was as easy as;

$ cd ~
$ git clone https://github.com/grz0zrg/fbg

If you don’t have git installed use the relevant apt-get command. The example files can then be found in the following directory;

$ cd ~/fbg/examples 

I then copied the quickstart.c file and hacked on it a little, modifying it like so;

#include <sys/stat.h>
#include <stdio.h>
#include <signal.h>
#include "fbgraphics.h"

int file_exists( const char* filename )
{
    //define file handle
    FILE *file;

    //attempt to open file read only
    if( (file = fopen(filename, "r")) )
    {
        fclose(file);    // release file handle
        return 1;        // tell someone we found it
    }
    else
    {
        return 0;         //no one home
    }
}

int main(int argc, char* argv[])
{
    const char* framebuffer_name = "/dev/fb1";
    const char* logo_filename = "logo.png";

    //check we have a framebuffer to talk to
    struct _fbg *fbg = fbg_setup( (char *)framebuffer_name, 0);
    if (fbg == NULL)
    {
        return -1;
    }

    // make sure logo file exists
    if( !file_exists( logo_filename ))
    {
        printf("File not found: %s\r\n",logo_filename);
        return -2;
    }

    //draw something on the display
    struct _fbg_img *logo = fbg_loadPNG(fbg, "logo.png");
    fbg_clear(fbg, 0);
    fbg_image(fbg, logo, 0, 0);
    fbg_flip(fbg);
    fbg_draw(fbg);

    //release memory
    fbg_freeImage(logo);
    fbg_close(fbg);

    return 0;
}

Which was built with the following command line from within the examples directory;

gcc ../src/lodepng/lodepng.c ../src/nanojpeg/nanojpeg.c ../src/fbgraphics.c display_logo.c -I ../src/ -I. -std=c11 -pedantic -D_GNU_SOURCE -D_POSIX_SOURCE -Wno-unused-value -Wno-unknown-pragmas -O2 -Wall -lm -o display_logo

Hacking upon the Makefile is also not that difficult, I simply added the relevant lines the SRC and OUT sections, then copied the quickstart section and renamed display_logo. There is lots of information about on how to do this on the internet so I’ll not repeat it again unnecessarily.

All I had to do then was place my 128×128 PNG file alongside the display_logo executable (renamed logo.png) and run it… wallah ! I was greeted by the AREG logo on my small OLED display in all of its 128×128 pixel glory; see the image at the top of this post.

So the next trick is to move this to the boot process… So by the looks the plymouth package might be the go, only one way to find out.