Intermittent Image Display Success

What do you want to achieve?

I would like to reliably display a PNG image from a file. I can successfully display just an image from a file. However, when I add another widget (for example’s sake, a rectangle), the image is not reliably displayed. Sometimes (maybe 1 out of every 10-20 times), the image displays correctly.

I am a beginner and often overlook things that may be obvious to those with more experience. Thanks for reading my post and any help or assistance you can provide. I have been pulling my hair out for several days trying to solve this.

What have you tried so far?

  • Printing lv_image_decoder_get_info() output. Regardless of whether the image is successfully displayed or not I get Decoder result=1, header=10 x 10 (correct dimensions).
  • Printing lv_obj_get_width(img) and lv_obj_get_height(img), after calling lv_obj_update_layout(img). Again, the correct values are listed, even when the image fails to display.
  • When the rectangle widget is removed, the image displays reliably.

Code to reproduce

    fat_init();
    bsp_display_start();
    bsp_display_lock(-1);

    lv_obj_t * scr1 = lv_screen_active();

    lv_obj_t * rect = lv_obj_create(scr1);
    lv_obj_set_pos(rect, 150, 150);
    lv_obj_set_size(rect, 200, 100);
    lv_obj_set_style_bg_color(rect, lv_color_hex(0xF17135), LV_STATE_DEFAULT);
    

    lv_obj_t * img = lv_image_create(scr1);
    lv_image_set_src(img, "A:/copy.png");
    lv_obj_set_pos(img, 220, 220);
    lv_obj_set_size(img, 10, 10);

    lv_obj_move_foreground(img);
    lv_obj_invalidate(img);

    bsp_display_unlock();

Screenshot and/or video

Environment

  • MCU/MPU/Board: Waveshare ESP32-S3-Touch-AMOLED-1.75C
  • LVGL version: 9.6.0
  • Decoder: Lode PNG

Hi @ejm ,

Thank you for opening this topic.

Looking your code, it appears that you are forcing an invalidation, however, the lv_image_set_src function already handles this process internally.

I suggest to remove this invalidation, as it is likely affecting the expected performance. Also, there is no need to explicitly move the image to the top of the screen, since LVGL organizes objects based on the order in which they were created.

Hi @halyssonJr, thanks for your suggestions. I added the invalidation just to try to force it to redraw. Similar logic for explicitly moving the image to the top. Unfortunately removing those lines did not resolve the issue.

I am trying to fix this issue through adjusting the project configuration file. When I turned on logging and set the verbosity to “trace” or “info” the image displays correctly and reliably. When I reduced the logging to “warn”, I got the following errors:

[Error] (1.523, +1523)   image_decoder_get_info: File open failed: 13 lv_image_decoder.c:433
[Warn]  (1.527, +4)      lv_draw_image: Couldn't get info about the image lv_draw_image.c:133

However, when I call lv_image_decoder_get_info() (which in turn calls image_decoder_get_info()) in app_main(), it returns success values. (see below)

    lv_image_header_t header = {0};

    lv_result_t result =
        lv_image_decoder_get_info("A:copy.png", &header);

    ESP_LOGI("IMG", "Decoder result=%d, header=%u x %u",
             (int)result,
             (unsigned)header.w,
             (unsigned)header.h);

    lv_obj_update_layout(img);
    ESP_LOGI("IMG", "Object size: %d x %d",
         (int)lv_obj_get_width(img),
         (int)lv_obj_get_height(img));

The logged results are

I (2504) IMG: Decoder result=1, header=10 x 10
I (2504) IMG: Object size: 10 x 10

I seem to be making some progress but I do not understand why the logging configuration should have this impact.

Well if anyone is making the same mistakes as me, I thought I might as well document the reason for the code not working as expected. Outside of what I provided in the snip in my original post I was calling ESP_ERROR_CHECK(esp_vfs_fat_spiflash_unmount_ro(base_path, "storage")). However, I did not realize that LVGL continues after app_main() finishes. As such, the image could not successfully be loaded before the filesystem was unmounted. I think I have a crude understanding of why changing the logging settings affected the results - basically by slowing everything down LVGL had sufficient time to decode and load the image before the filesystem was unmounted.