Decoded image from SD card does not work with LVGL


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


What LVGL version are you using?


What do you want to achieve?

Successfully fetching an image from an SD card, then pass the C array to the image structure and set it as lv_img_dsc_t and display the image.

What have you tried so far?

I firstly tried create a function that returns lv_img_dsc_t, it takes a String of a filename, then fetch from an SD card. Then I will use a library (JpegDecoder - Bodmer) that decode the necessary info for this tasks. After that, I then read the data and copy it to the allocated array.
then I created a structure which contains all the information of the lv_img_dsc_t, and return the object
I have checked and confirmed that it does not result in a memory error.
After all, all I get was a completely blurred and unrecognizable image

Code to reproduce

lv_img_dsc_t loadimage(String filename)
    File file =, FILE_READ);
    if (!file) return lv_img_dsc_t();
    bool dec = JpegDec.decodeSdFile(filename);
    if (!dec) return lv_img_dsc_t();
    //Serial.printf("Width: %d, Height: %d\n", JpegDec.width, JpegDec.height);

    uint8_t *imagemap = new uint8_t[file.size()];
    int pos = 0;
    while (file.available())
      imagemap[pos] = (uint8_t);
    Serial.printf("pos: %d\n", pos);

    lv_img_dsc_t image = {
            LV_IMG_CF_TRUE_COLOR,     // Header CF
            0,                        // header.alwayszero
            0,                        // Unknown
            JpegDec.width,  // Width
            JpegDec.height, // height
        JpegDec.width * JpegDec.height * LV_COLOR_SIZE / 8, // data size
        imagemap,                               // data
    return image;

void initLVGL() {
    lv_disp_draw_buf_init(&draw_buf, buf1, NULL, TFT_WIDTH * TFT_HEIGHT / 10);  /*Initialize the display buffer.*/
    lv_disp_drv_init(&disp_drv);          /*Basic initialization*/
    disp_drv.flush_cb = my_disp_flush;    /*Set your driver function*/
    disp_drv.draw_buf = &draw_buf;        /*Assign the buffer to the display*/
    disp_drv.hor_res = TFT_WIDTH;   /*Set the horizontal resolution of the display*/
    disp_drv.ver_res = TFT_HEIGHT;   /*Set the vertical resolution of the display*/

    //LVGL registering
    lv_disp_t *disp = lv_disp_drv_register(&disp_drv);

    lv_indev_drv_init(&indev_drv);             /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    disp->refr_timer->period = (uint32_t)(1000 / FPS);

    //Create a theme
    image = loadimage("/images/image.jpg");
    theme = lv_img_create(lv_scr_act());
    lv_img_set_src(theme, &image);
    lv_obj_set_width(theme, LV_SIZE_CONTENT); /// 1
    lv_obj_set_height(theme, LV_SIZE_CONTENT);
    lv_obj_set_align(theme, LV_ALIGN_CENTER);

I’m not so sure if I have done anything wrong here. I appreciate any help if anyone can spot the mistake here.
Thank you!