PNG decoder called many times before displaying the Image

Hello all
I am using LVGL V8 arduino library, with ESP32S3, finally I was able to load a 100x100 PNG image from SD card, using PNG Decoder (lv_png.c).
Here is the part of my code creating this image:

ui_Image2 = lv_img_create(ui_Screen1);
lv_obj_set_width(ui_Image2, LV_SIZE_CONTENT);   /// 1
lv_obj_set_height(ui_Image2, LV_SIZE_CONTENT);    /// 1
lv_obj_set_x(ui_Image2, 0);
lv_obj_set_y(ui_Image2, 0);
lv_obj_set_align(ui_Image2, LV_ALIGN_CENTER);
lv_img_set_src(ui_Image2, "S:/wifi100.png");

I turned on logging to make some debugging, and I see that decoder_open is called 10 times, and then no more calls, even though I use “lv_img_set_src” just once.
At this specific line (lv_png.c #156), I added:
LV_LOG_WARN(“error %u: %s\n”, error, lodepng_error_text(error));

[Warn]  (1.160, +1160)   decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (1.302, +142)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (1.443, +141)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (1.584, +141)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (1.725, +141)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (1.867, +142)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (2.008, +141)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (2.149, +141)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (2.291, +142)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)
[Warn]  (2.434, +143)    decoder_open: pngdatasize is 40035, width , 100, height, 100   (in lv_png.c line #156)

No more prints afterwards from lv_png.c

In order to check if it a problem of refresh, or other calls to “lv_timer_handler”,
I added a text box which increments its value in the while loop:

void loop()
{
    lv_timer_handler(); /* let the GUI do its work */
    lv_label_set_text(ui_lblIP, ((String)i).c_str()); // worked just fine , carefull for overflow
    i++;
    delay (1000);
}

I can confirm that decode_png is not called when lv_timer_handler is called repeatedly during the loop, it is called until all the PNG image is loaded, but the strange thing is that it is repeated 10 times.
Thank you

Hi,

How many lines do you have as draw buffer? (in lv_disp_draw_buf_t)?

You can set LV_IMG_CACHE_DEF_SIZE in lv_conf.h to cache the decoded images.

Thank you for your reply .
It is solved by setting the LV_IMG_CACHE_DEF_SIZE to 2 * 1024
My draw_buf.size is equal to 4800 , if that what you meant by “how many lines as draw buffer” .

It should be 2, as it set’s the number of images to to keep cached, not the max cache memory size.

You can get the number of lines if you divide 4800 by the horizontal resolution of your display. Is 4800 bytes or pixels?

I set it to 2, and it is working :+1:

My screen resolution is 480 * 320 pixels.
I am initiliazing the buffer as follows:

 lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 ); // screenWdith = 480
 Serial.println(draw_buf.size);// this outputs 4800 (which is screenWidth * 10)

I copied this intialisation line from some sample code, I am not sure if multiplying by 10 is the right number

You saw 10 PNG decoder open calls without caching as with 10 lines of buffer (screenWidth * 10) the 100x100 image was drawn in 10 parts.

To improve performance in general I suggest using screenWidth * screenHeight / 10 (1/10 screen sized) buffer.

Thank you for the valuable information.