How to load PNG file from sd card to lv_img's object?

Description

By this article https://blog.littlevgl.com/2018-10-05/png_converter.

I can decode sd’s png file to png_decoded data by lodepng_decode_file() ,
but when set src to lv_img’s obj, the result that shown on the TFT seems a mistake.
How to fix the issue?

(The code as the following part.)

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

  • ESP32
  • lvgl 6.0.2

What do you want to achieve?

Wish to display sd’ png_file correctly.

What have you tried so far?

Code to reproduce

  const char*     png_filename = "/sd/images/08.PNG";  // this png file is PNG_RGBA8 type
  static uint8_t* png_decoded;
  uint32_t        png_width, png_height; 
  LodePNG_format  png_format=PNG_BADFORMAT;

  uint8_t error = lodepng_decode_file(&png_decoded, &png_width, &png_height, &png_format, png_filename ); 
  if(error)  {
    Serial.println(lodepng_error_text(error));
    return;
  }

  Serial.printf("PNG : %s ; wxh : %dx%d ; format : %d\n", png_filename, png_width, png_height, png_format);

  static lv_img_dsc_t png_dsc;
  png_dsc.header.always_zero  = 0;                          /*It must be zero*/
  png_dsc.header.cf           = LV_IMG_CF_TRUE_COLOR_ALPHA;      /*Set the color format*/
  png_dsc.header.w            = png_width;
  png_dsc.header.h            = png_height;
  png_dsc.data_size           = png_width * png_height * 4;
  png_dsc.data                = png_decoded;

  lv_obj_t * img_obj = lv_img_create(lv_scr_act(), NULL);     /*Create the an image object in LittlevGL*/
  lv_img_set_src(img_obj, &png_dsc); 

The result on serial monitor :

PNG : /sd/images/08.PNG ; wxh : 320x240 ; format : 3

( format 3 is PNG_RGBA8 )

Screenshot and/or video

The result on TFT’s screen.

Hi,

I’ve update the mentioned blog post.
See this section

It’s much easier to just png_decoder_init() and use the pass the filename to lv_img_set_src().

Already can display png file ,
however the color of any picture is strange from original file.

Screenshot

image

CODE

  lv_obj_t * img_obj = lv_img_create(lv_scr_act(), NULL); 
  lv_img_set_src(img_obj, "/sd/images/04.png");

Take a look at convert_color_depth() in png_decoder.c. Probable Red and Blue needs to be swapped.

OK, done by swapping between red and blue.

Another question,
If the png file is RGB-888 type (not RGBA-8888 type) ,
in the function decoder_info() , I must set

from

header->cf = LV_IMG_CF_RAW_ALPHA;

to

header->cf = LV_IMG_CF_RAW;

And in function convert_color_depth() , must impliment

from

img[i*3 + 2] = img_argb[i].ch.alpha;
img[i*3 + 1] = c.full >> 8;
img[i*3 + 0] = c.full & 0xFF;

to

img[i*2 + 1] = c.full >> 8;
img[i*2 + 0] = c.full & 0xFF;

Isn’t it ?

I didn’t try it but it seems correct.

When I set image to lv_img’s obj like this

lv_obj_t * img_obj = lv_img_create(lv_scr_act(), NULL); 
lv_img_set_src(img_obj, "/sd/images/04.png");

If the other time, I want to change the img_obj to another png_file again ,
by calling lv_img_set_src() like this,

lv_img_set_src(img_obj, "/sd/images/05.png");

Or some situations , I want to delete img_obj by lv_obj_del()

The question is ,
does the lv_img’s obj automatically free previous allocated png_decoded data?
If not, how to free previous allocated png_decoded data?

Thank you.

If LV_IMG_CACHE_DEF_SIZE 1 then only 1 image will be kept opened.
Learn more here: https://docs.littlevgl.com/en/html/overview/image.html#image-caching

And how about when img_obj is deleted bylv_obj_del() ?
does the img_obj automatically free previous allocated png_decoded data?

On deleting the image remains open. It’s because the same image source can be used by multiple image objects.
You can clean the cache manually on delete.

Thank you very much.

You’re welcome!

Do you know how to load JPG file from SD card?

I have the same problem,could you help me?

lvgl can show jpg file form my sdcard
i use esp32 + tft 9448 spi interface.

If it’s a question, then see this repo https://github.com/lvgl/lv_lib_split_jpg

thank you sir.

How to ADD my font in key board widget

I am trying to open/read jpg file from SD card mounted on mimxrt1064, and using lvgl I want to display on LCD. if any solution then please share.

lv_fs_if, but you need a sufficient amount of RAM, I still did not understand how to output JPG in chunks

But i don’t get that how to load images directly from SD card.