Arduino GiGA Display Image from USB Using LVGL - Blank screen - Help

Dear All,
I spent weeks try to find a solution and spare this humble community with my lack of talent.
Here is the pitch:
First i am a noob ! I bought the Giga display bundle (with the board and the touch screen).
I want for a project, to use LVGL lib to display an image. I succeeded to include images in the code but with 8 pictures i am using all the memory (LVGL converter and .c files stuff).
So i am now using an USB to load the picture and to read some .txt files.
Mounting the USB done
Reading the .txt files done
Reading all images files titles done.

Trying to display the pictures in every way possible.... Fail... the printf tells me it is displaying the picture but I end up with a white screen. I have tried all sorts of images type, .bmp . jpg ,800x480 pixels, 300x300 pixels, 100x100 pixels, 24 bits, 16bits.

I went through out the forums trying to do it on my own .... any one have an idea ?

Thank you in advance

#include <Arduino_H7_Video.h>        // GIGA display driver (includes LVGL)
#include <lvgl.h>                    // LVGL library
#include <Arduino_USBHostMbed5.h>    // USB Host for GIGA R1
#include <FATFileSystem.h>           // FAT file system (mbed)

// Display object
Arduino_H7_Video Display;
// USB mass storage object
USBHostMSD usb;
// File system mounted on "/usb"
mbed::FATFileSystem fs("usb");

// Global pointer for the LVGL image object
lv_obj_t *img_obj = NULL;

// Variables for image switching
bool showingBmp = true;
unsigned long lastSwitch = 0;

void setup() {
  Serial.begin(115200);
  
  // Initialize LVGL and display
  lv_init();
  Display.begin();  // Configure the screen and LVGL

  // Connecting USB stick
  Serial.print("Connecting USB...");
  while (!usb.connect()) {
    Serial.println("Waiting for the USB stick...");
    delay(100);
  }
  Serial.println("USB stick connected.");

  // Mounting USB file system
  Serial.print("Mounting file system...");
  int err = fs.mount(&usb);
  if (err != 0) {
    char buffer[50];
    sprintf(buffer, "Mount error (%d)", err);
    Serial.println(buffer);
  } else {
    Serial.println("File system mounted!");
  }
  
  // Checking for file existence in the testimages folder
  FILE *f = fopen("/usb/testimages/logo300bittest.bmp", "rb");
  if (!f) {
    Serial.println("BMP file not found (check path and filename).");
  } else {
    Serial.println("BMP file found.");
    fclose(f);
  }
  
  f = fopen("/usb/testimages/logo300bittest.jpg", "rb");
  if (!f) {
    Serial.println("JPG file not found (check path and filename).");
  } else {
    Serial.println("JPG file found.");
    fclose(f);
  }
  
  // Initial creation of the image object and display of the BMP
  img_obj = lv_img_create(lv_scr_act());
  // Note: For LVGL via STDIO, the path must be prefixed with "S:" (letter assigned to the driver)
  lv_img_set_src(img_obj, "S:/usb/testimages/logo300bittest.bmp");
  lv_obj_align(img_obj, LV_ALIGN_CENTER, 0, 0);
  
  // Indicate that the BMP is initially displayed and initialize the timer
  showingBmp = true;
  lastSwitch = millis();
}

void loop() {
  // Periodic LVGL handling
  lv_timer_handler();  
  delay(5);
  
  // Image change every 5000 ms
  if (millis() - lastSwitch > 5000) {
    lastSwitch = millis();
    // Delete the previous image
    lv_obj_del(img_obj);
    // Create a new image
    img_obj = lv_img_create(lv_scr_act());
    
    if (showingBmp) {
      Serial.println("Displaying logo300bittest.jpg");
      lv_img_set_src(img_obj, "S:/usb/testimages/logo300bittest.jpg");
    }
    else {
      Serial.println("Displaying logo300bittest.bmp");
      lv_img_set_src(img_obj, "S:/usb/testimages/logo300bittest.bmp");
    }
    
    lv_obj_align(img_obj, LV_ALIGN_CENTER, 0, 0);
    // Toggle the flag for the next switch
    showingBmp = !showingBmp;
  }
}


Because I asked, i just found the solution....
first
.BMP image needs to be in 16bit
.JPG image needs to be set as a "baseline" (non-progressive) JPEG

  1. Set JPEG options
  • A new Export Image as JPEG dialog will appear with quality and advanced options.
  • Uncheck “Progressive” if you see that option (depending on GIMP version, it may be called “Use progressive JPEG” or something similar). Unchecking it ensures your image is exported as a baseline JPEG.
  • Set Quality to an appropriate value (for example, around 85–100 for high quality).
  • Make sure Optimize is checked if you want smaller file size (this does not affect baseline vs. progressive).
  • Ensure the Color Profile is standard sRGB (usually the default) and not CMYK.

Secondly you need to mount the USB with a driver as follow (couldnt make STDIO work...) :

#include <Arduino_H7_Video.h>        // GIGA display management
#include <lvgl.h>                    // LVGL library
#include <Arduino_USBHostMbed5.h>    // USB Host for GIGA R1
#include <FATFileSystem.h>           // FAT file system (mbed)
#include <stdio.h>                   // For fopen, fread, etc.

// --- Global objects ---
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
USBHostMSD usb;
mbed::FATFileSystem fs("usb");  // Mounts the USB stick on the path "/usb"

// --- Register the file system driver for LVGL ---
void register_lvgl_fs_driver() {
    static lv_fs_drv_t fs_drv;
    lv_fs_drv_init(&fs_drv);
    fs_drv.letter = 'U';  // Files are accessed via "U:"
    
    // Callback to open a file
    fs_drv.open_cb = [](lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode) -> void* {
        LV_UNUSED(drv);
        char fullPath[128];
        // Constructs the full path by appending the mount point "/usb/"
        snprintf(fullPath, sizeof(fullPath), "/usb/%s", path);
        const char *modeStr = "rb";  // read-only by default
        if(mode & LV_FS_MODE_WR) {
            modeStr = "rb+";
        }
        FILE *fp = fopen(fullPath, modeStr);
        return (void*)fp;
    };
    
    // Callback to read from a file
    fs_drv.read_cb = [](lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br) -> lv_fs_res_t {
        LV_UNUSED(drv);
        FILE *fp = (FILE*) file_p;
        *br = (uint32_t)fread(buf, 1, btr, fp);
        return LV_FS_RES_OK;
    };
    
    // Callback to close a file
    fs_drv.close_cb = [](lv_fs_drv_t *drv, void *file_p) -> lv_fs_res_t {
        LV_UNUSED(drv);
        fclose((FILE*)file_p);
        return LV_FS_RES_OK;
    };
    
    // Callback to reposition the file pointer
    fs_drv.seek_cb = [](lv_fs_drv_t *drv, void *file_p, uint32_t pos, lv_fs_whence_t whence) -> lv_fs_res_t {
        LV_UNUSED(drv);
        FILE *fp = (FILE*) file_p;
        int seek_from = SEEK_SET;
        if(whence == LV_FS_SEEK_CUR) seek_from = SEEK_CUR;
        else if(whence == LV_FS_SEEK_END) seek_from = SEEK_END;
        fseek(fp, pos, seek_from);
        return LV_FS_RES_OK;
    };
    
    // Callback to get the current position
    fs_drv.tell_cb = [](lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p) -> lv_fs_res_t {
        LV_UNUSED(drv);
        FILE *fp = (FILE*) file_p;
        *pos_p = ftell(fp);
        return LV_FS_RES_OK;
    };
    
    lv_fs_drv_register(&fs_drv);
}

void setup() {
    Serial.begin(115200);
    
    // Initialize LVGL and the display
    lv_init();
    Display.begin();
    
    // Register the custom FS driver for LVGL
    register_lvgl_fs_driver();
    
    // --- USB connection and mounting ---
    Serial.print("Connecting USB...");
    while (!usb.connect()) {
        Serial.println("Waiting for the USB stick...");
        delay(100);
    }
    Serial.println("USB stick connected.");
    
    Serial.print("Mounting the file system...");
    int err = fs.mount(&usb);
    if (err != 0) {
        Serial.print("Mount error: ");
        Serial.println(err);
        while (1) delay(1000);  // Blocks execution if the mount fails
    } else {
        Serial.println("File system mounted!");
    }
    
    // --- Checking the file ---
    FILE *f = fopen("/usb/logo300bittest.bmp", "rb");
    if (!f) {
        Serial.println("logo300bittest.bmp file not found!");
    } else {
        Serial.println("logo300bittest.bmp file found.");
        fclose(f);
    }
    
    // --- Display the image with LVGL ---
    lv_obj_t *img_obj = lv_img_create(lv_scr_act());
    // Note: The path uses the letter 'U' (our FS driver) to access the file:
    lv_img_set_src(img_obj, "U:/logo300bittest.bmp");
    lv_obj_align(img_obj, LV_ALIGN_CENTER, 0, 0);
}

void loop() {
    lv_timer_handler();  // Updates LVGL
    delay(5);
}



and of course the good old lv_conf.h modification:

#define LV_USE_BMP    1    
#define LV_USE_TJPGD  1   

hope it will save some time to others. I was painful for me to get there :sweat_smile:

Now i need to faster the display of the image wich is quite slow
any ideas ?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.