Question lv_img

hello,

I’m new to littlevgl. Today, I got a issue about jpg display. I found the online https://littlevgl.com/image-to-c-array always output a big .c file for a jpg image.
I’m using esp8266 for testing, it always complie error, it seems no RAM enough,however, I use a lib named “TJpg_Decoder”, it cloud work and output the same jpg for me.
I guess littlevgl must keep the data of jpg image(in RAM) currently, is that right ?
is that possible to make the c array smaller ? or change it as .h ?

I have a question, there are 2 ways I guess this lib to deal with jpg image.
1)this image must keep in RAM till it been replaced. some image, once it been background, and a transparent container in the top of the background, the lib must need to re-calculate colors, and fill it again. so , it must be in RAM.
2) the RAM will be set free after used. once it been background, and a transparent container in the top of the background, the lib will read colors from hardware, and re-calculate colors and fill it one by one.

Is there someboday who can tell me the way about littlevgl handling the image ?

thanks.

What would you expect? If you set C array as output format, it will create C array.

I don’t really understand what is your goal. So you have a “normal” JPG image, but want to store it in the flash of MCU, and use “TJpg_Decoder” to display an image from it.

If so, you should choose the “Raw” color format in the converter. “True color” output format will save decompressed image (pixel by pixel), but “Raw” will output the JPG file as it is (byte by byte).

  1. in esp8266, the .c array is too big, and it’s over the RAM of esp8266.
  2. I try to use RAW format(.bin) file, but it seems error, I can not read it from spiffs. it not works. it seems the same issue with here: https://github.com/littlevgl/lv_arduino/issues/41#issuecomment-619830641 .
  3. I try to use TJpg_Decoder for drawing the same jpg , it use this converter(http://tomeko.net/online_tools/file_to_hex.php?lang=en) , and this lib can read image from .h , and it works fine for esp8266 .
  4. this jpg image is beening as background(a 320x480 jpg image, that’s why it go so big). So I wanna to ask, is that possbile to use TJpg_Decoder for drawing the jpg as background ?does the transparent container will cover it ? or the littlevgl would cover it ?

or, my question is: is that possbile to draw the background with TJpg_Decoder dedicatedly , and let the littlevgl draw transparent container ? will that works ?

As a beginner of littlevgl , I’m still learning how to make a transparent container.

I tried it(draw background image via TJpg_Decoder) just now, it seems not works. here is the code:

void display_service::lv_main()
{
  lv_obj_t *scr = lv_cont_create(NULL, NULL);
  lv_disp_load_scr(scr);
  
  static lv_style_t style_tv_bg;
  lv_style_copy(&style_tv_bg, &lv_style_plain);
  style_tv_bg.body.opa = LV_OPA_TRANSP;
  style_tv_bg.body.border.width = 0;

  lv_obj_t *body = lv_cont_create(lv_disp_get_scr_act(NULL), NULL);
  lv_obj_set_pos(body, 0, 0);
  lv_obj_set_size(body, lv_disp_get_hor_res(NULL) - 4, lv_disp_get_ver_res(NULL) - 2);

  jpg_draw(jpg_logo, sizeof(jpg_logo), 100, 200, ROTATION, 1, TFT_BLACK);
  
  lv_cont_set_style(body,LV_CONT_STYLE_MAIN,&style_tv_bg);
}

void display_service::jpg_draw(const uint8_t jpgname[], uint32_t jpg_size, int xx, int yy, byte Rotation, byte Scale, uint16_t color)
{
  tft.fillScreen(color);
  tft.setRotation(Rotation);

  TJpgDec.setJpgScale(Scale);
  // The byte order can be swapped (set true for TFT_eSPI)
  TJpgDec.setSwapBytes(true);

  // The decoder must be given the exact name of the rendering function above
  TJpgDec.setCallback(tft_output);

  uint16_t w = 0, h = 0;
  TJpgDec.getJpgSize(&w, &h, jpgname, jpg_size);
#ifdef _DEBUG_
  Serial1.print(F("   [INFO] Jpg Logo infos:\n"));
  Serial1.print(F("   =================================\n"));
  Serial1.print(F("   [INFO] Jpg Logo Width: "));
  Serial1.println(w);
  Serial1.print(F("   [INFO] Jpg Logo Height: "));
  Serial1.println(h);
  Serial1.print(F("   =================================\n"));
#endif
  TJpgDec.drawJpg(xx, yy, jpgname, jpg_size);
  ESP.wdtFeed();
}

does my code wrong ? or it is impossible to use littlevgl like this ?
is there resolution ?

Let me to clarify how it works in LVGL. You can store the raw image (jpg as it is) in ROM or on SD card (or any external device).
To access files on the SD card you need a “driver” in LVGL (some functions for file operations) to let handling the files as it needs. This driver interface allows to use any file system with LVGL.
You can read more bout it here: https://docs.littlevgl.com/en/html/overview/file-system.html

Once you can read the image from SD card or ROM, LVGL needs to know how to decode that image. Similarly to file systems you can attach any image decoders to LVGL via a simple interface. See here: https://docs.littlevgl.com/en/html/overview/image.html#image-decoder
For JPG and PNG it’s usually not supported to extract only a partion of the image which would be required e.g. if you change a label on the image. Therefore typically you should decompress a the whole image al let LVGL to use it as raw pixel map. See this PNG decoder as reference.

Note that you can’t mix 2 GUI libraries. That is, you shouldn’t draw with your custom drawers and LVGL at the same time, as they won’t know about each other and can’t refresh dirty areas correctly.

thanks.

How about use it with the SPIFFS(esp32/esp8266) ? can you please make a example ?

We don’t have a ready to use example now, but it’d be possible to have one.

There is a repo where we can add support to various file systems. It’d nice to the have support to ESP files system there.

@Carlos_Diaz Have you already tried to integrate ESP file system to lv_fs?

@kisvegabor No, I haven’t, I will have some free time this weekend to give it a try.

2 Likes