How to use LVGL built in image decoder to display a png to the screen?

Description

Hi, I’m trying to display a png to the screen by opening it from the file path “/mnt/flash/nexion.png”. However, every time I try to open this file up using the line img_set_src(img, “/mnt/flash/nexion.png”), I’m told that the file cannot be opened because it contains an unknown driver letter. The error is: lv_fs_open: Can’t open file ("/mnt/flash/nexion.png): unknown driver letter. I’m not sure why it is even using lv_fs_open to begin with. On this website: https://github.com/lvgl/lv_lib_png, it says that by deafult lodepng uses C file IO API (e.g. fopen) and images can be opened like this:

lv_img_set_src(img, “./lv_lib_png/png_decoder_test.png”). fopen works for me when using the call fopen("/mnt/flash/testfile.txt") so why would it not work when I’m setting the img_src in the same way?

What MCU/Processor/Board and compiler are you using?

Xilinx Zyng Development Board

What LVGL version are you using?

Version 8.1

What do you want to achieve?

I want to render a png to the screen without having to use the online decoder. I want to decode the png image to a C file and display it right away on the screen. I don’t mind doing so in a longer way - like using lodepng directly instead of using the lv_img_set_src function. However, I do not know what function to call to do so

What have you tried so far?

I have tried putting the png file in a folder on my windows C drive and using the absolute path in the call set_img_src(img, “C:/users/matth/…”). I had to register a driver to do so in main.c but had no luck with it and the documentation was not easy to follow. I added #define LV_USE_PNG 1 in lv_conf.h and lv_conf_internal.h. Then I added the snippet of code below to a testing page but it gives me the error of an unknown driver letter described above and an inability to properly open the file.

Code to reproduce

The code block(s) should be formatted like:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "../lvgl/lvgl.h"
#include "controlTab.h"
#include "global.h"
#include "../lvgl/src/extra/libs/png/lv_png.h"

/*       STATIC - PRIVATE VARIABLES        */
static lv_obj_t * backButton;
static lv_obj_t * container;

static lv_obj_t * chart;
static lv_chart_series_t * ser;
static lv_chart_cursor_t * cursor;

/* FUNCTION DECLARATIONS */
static void BackButtonPressed(lv_event_t * event);

void TestingPageInit(void)
{
	container = lv_obj_create(controlTab);
	lv_obj_set_size(container, lv_obj_get_width(controlTab), lv_obj_get_height(controlTab)/2);
	lv_obj_center(container);

	lv_obj_t * label = lv_label_create(container);

	backButton = lv_btn_create(controlTab);
	lv_obj_align(backButton, LV_ALIGN_CENTER, -290, 110);
	lv_obj_set_size(backButton, 120, 60);
	lv_obj_t *label1 = lv_label_create(backButton);
	lv_label_set_text(label1, LV_SYMBOL_BACKSPACE " BACK");
	lv_obj_add_event_cb(backButton, BackButtonPressed, LV_EVENT_CLICKED, NULL);

	lv_png_init();
	//LV_IMG_DECLARE(png_decoder_test);
	lv_obj_t * img = lv_img_create(lv_scr_act());
	//lv_img_set_src(img, "./mnt/flash/nexion.png");
	lv_img_set_src(img, "P:/users/matth/downloads/nexion.png");


}

The latest version of my code uses the line
lv_img_set_src(img, "/mnt/flash/nexion.png"); instead of lv_img_set_src(img, “P:/users/matth/downloads/nexion.png”);

Hi,

You need to register an FS driver for LVGL or enable one. See File system — LVGL documentation

1 Like

@kisvegabor thank you for your reply! I did look at that page. However, I do not know how to implement an open, size, read, and close callback. How do I write these callbacks? The documentation only tells me how to write the prototypes of these functions. Alternatively, is there anyway to open the file using the standard fopen instead of registering a driver? @embeddedt if I could get your help too that would be great!

Hi, if all you’re looking to do is use the stdio functions; you can just enable that in lv_conf.h here. Writing your own callbacks is only necessary if you have your own filesystem interface you want to make work with LVGL. See the documentation for more info.

1 Like

@embeddedt thank you for your response. Previously I tried enabling the LV_USE_FS_STDIO in lv_conf_template.h. However, I soon realized that I should have copy pasted the lines #define LV_USE_FS_STDIO ‘P’ /Uses fopen, fread, etc/
#define LV_FS_STDIO_PATH “/mnt/flash/” /*Set the working directory. If commented it will be “./” */ into lv_conf.h. I also did not know that I was supposed to pick a letter at random to use - I thought this letter needed to be a specific one like ‘C’ for my windows C drive. However, I just picked the letter P and in one of my .c files I pasted the line lv_img_set_src(img, "P:nexion.png"); and it worked. Thank you!

1 Like

@embeddedt and @kisvegabor I just have one more question/concern, when I try to set the src of the image to a file greater than approximately 8.5 kb, I get the following error in the console. I think I’m running out of memory - is there any way to create more memory or move it so I can load larger png files on the screen?

You can increase LV_MEM_SIZE in lv_conf.h, but if you’re on a Linux platform, you might just want to enable LV_MEM_CUSTOM and use the system heap.

1 Like

Thank you @embeddedt! Increasing LV_MEM_SIZE did allow me to display the png but scrolling the png around made the entire screen lag. I tried increasing the display buffer size in main.c but that did not resolve the issue. However, I noticed that when I load the png image from a pre-converted file and use LV_IMG_DECLARE(variable name from binary C file), it does not lag at all. Do you know if there is anyway I can use lodepng to generate this C binary file so that the scrolling is a lot smoother? And after generating the RGBA values in the C binary file how would I create a struct to declare the image and eventually display it on the screen?

Did you happen to find an answer as to why pre-converting an image makes the lag go away? We have gif and png that unless pre-converted will lag upon animating. Lag occurs when any animation occurs and at least one displayed image is not pre-converted.