Description
What MCU/Processor/Board and compiler are you using?
ESP32-WROOM
What LVGL version are you using?
8.0
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 = SD.open(filename, 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)file.read();
pos++;
}
Serial.printf("pos: %d\n", pos);
file.close();
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() {
display.clear();
display.setSwapBytes(true);
lv_init();
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!