LVGL image not displaying

Here is my code:

#include “main.h”
lv_obj_t * createImage(lv_coord_t x, lv_coord_t y, lv_coord_t width, lv_coord_t height, int id,const void *src_img){
lv_obj_t * image = lv_img_create(lv_scr_act(), NULL);
lv_img_set_src(image,src_img);
lv_obj_set_size(image, width, height);
lv_obj_set_pos(image, x, y);
lv_obj_set_free_num(image, id);
return image;
}
void initialize()
{
createImage(1,1,100,100,0,“S:pic.bin”);
}

No error is shown but it displays an empty screen.

I personally have not had any luck getting the SD card image reading to work. There might be a problem in the backend.
Instead use the image to c array convertor (5.1 version).
Btw I believe the correct path to the SD card is "/usd/pic.bin", you can try that.

Oh no… I tried the array method before but there is 1200 lines of code and my laptop is lagging hard

Well you shouldn’t have to open the file (unless you need to fix the include at the top - in that case just use notepad to make the change).
It sounds like your image is too big, make sure you are only using the V5’s dimensions of 480x240.

If you look through the source code for JPearman’s Animated GIF demo, there is no prefix or directory name for the gif file - try passing just “pic.bin” and see if it works.

Then, from the source code for lv_img_set_src() function it looks like it expects the image file with the specific header data. (there are several places where it is called in PROS).

I assume you already have such header…

If there is still no luck, gifdemo/include/gifclass.h has vex::Gif::Gif() and vex::Gif::render() methods that load gif image and display it on screen using direct calls into vexOS.

I understand that you want to do it with PROS and LVGL, but it has an examples of calling vexDisplayCopyRect(), which is also used by PROS.

Ok i will try when i return home. Thanks

According to the lvgl docs,

lv_img_set_src(lv_obj_t *img, const void *src_img);

works two ways.
The first parameter is the lv_obj_t* lvgl image object to apply the source to.
The second parameter is a pointer to the image source.
The image source can either be a pointer to a generated array embedded in the code, or it can be a string pointing to a file location. LVGL automatically detects the input type.

The problem here is that giving it a string to a file location does not work. However, the array method works.

In the LVGL docs, the example to use an external source is lv_img_set_src(img,"S:folder1/my_img.bin"). To use the array method, you need to forward declare the image file (which lives in a c file generated by the lvgl website) with LV_IMG_DECLARE(my_img) and then pass a pointer to the lv_img_set_src function.
According to the pros docs, the filesystem is accessed using "usd/my_img.bin". Interesting that the GIF demo does not use the usd/ prefix, VEXCode or VEXos must automatically prepend that when opening a file.

I have had success writing to files on the SD through PROS using the prefix, but not without. I think the problem is with lvgl or the way it is configured in PROS.

All those places are inside the lvgl header and source files, located in lvgl objects that use images. It does not implement or use any image, so does not give indication it works.

You could use vexDisplayCopyRect, provided you give the forward declaration and do not use LVGL. However, using the c array method is still the best option.

I tried some of this on Sunday, couldn’t get it to work. I will try again at some point. The PROS team really needs to update lvgl to the latest to help with the bin file creation, the file format has changed between the version they have and the latest.

Yeah, work is under way in this PR.
I think it is pretty much ready to be released, but there might be a bug or problem that has yet to be fixed.
There is a download in that PR you could apply to your project if you wanted to use the newer version (5.3).
Unfortunately, in the time PROS has taken to upgrade LVGL, a new version has come out (6.0), so they will probably have to start over again.
Hopefully they will be able to upgrade it soon.

Does anyone have any luck displaying an image with lvgl? Can you show me a bit of your source code eg.lv_img_set_src(imageptr,"S:pic.bin");? Or can you tell me what is wrong with my code? Thanks a lot!

Did you read this thread? No, no one has had any luck, there is something wrong, you need to use the c array.
The proper way of accessing a file is lv_img_set_src(imageptr,"usd/pic.bin"); but that does not work.

1 Like

yes, but one of my friends did it, but he wants me to try myself (its hard to explain our relationship its not like he hate me or what) i will tell you if he answers me

He has had success with displaying an image from the SD card using LVGL?
Because if he used VEXCode or RMS, they have a way to display from the SD that works.
He could have also used the convertor.
Are you sure he was using LVGL with the SD card?
How about you get him to post here, we are all curious how he did it.

Here’s a working example that displays image from SD Card with the version of lvgl that’s currently in PROS. It’s based on the lvgl sample code, unfortunately that’s either been updated for V6 or is just plain wrong, I don’t know.

#include <stdio.h>
#include "main.h"

typedef  FILE * pc_file_t;

static lv_fs_res_t pcfs_open( void * file_p, const char * fn, lv_fs_mode_t mode)
{
    errno = 0;
    const char * flags = "";
    if(mode == LV_FS_MODE_WR) flags = "wb";
    else if(mode == LV_FS_MODE_RD) flags = "rb";
    else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = "a+";

    char buf[256];
    sprintf(buf, "/%s", fn);
    pc_file_t f = fopen(buf, flags);

    if(f == NULL)
      return LV_FS_RES_UNKNOWN;
    else {
      fseek(f, 0, SEEK_SET);
      pc_file_t * fp = (pc_file_t *)file_p;
      *fp = f;
    }

    return LV_FS_RES_OK;
}

static lv_fs_res_t pcfs_close( void * file_p)
{
    pc_file_t * fp = (pc_file_t *)file_p;
    fclose(*fp);
    return LV_FS_RES_OK;
}

static lv_fs_res_t pcfs_read( void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
    pc_file_t * fp =  (pc_file_t *)file_p;
    *br = fread(buf, 1, btr, *fp);
    return LV_FS_RES_OK;
}

static lv_fs_res_t pcfs_seek( void * file_p, uint32_t pos)
{
    pc_file_t * fp = (pc_file_t *)file_p;
    fseek(*fp, pos, SEEK_SET);
    return LV_FS_RES_OK;
}

static lv_fs_res_t pcfs_tell( void * file_p, uint32_t * pos_p)
{
    pc_file_t * fp =  (pc_file_t *)file_p;
    *pos_p = ftell(*fp);
    return LV_FS_RES_OK;
}

void opcontrol() {
    lv_fs_drv_t pcfs_drv;                         /*A driver descriptor*/
    memset(&pcfs_drv, 0, sizeof(lv_fs_drv_t));    /*Initialization*/

    pcfs_drv.file_size = sizeof(pc_file_t);       /*Set up fields...*/
    pcfs_drv.letter = 'S';
    pcfs_drv.open = pcfs_open;
    pcfs_drv.close = pcfs_close;
    pcfs_drv.read = pcfs_read;
    pcfs_drv.seek = pcfs_seek;
    pcfs_drv.tell = pcfs_tell;
    lv_fs_add_drv(&pcfs_drv);

    lv_obj_t * img_var = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_src(img_var, "S:/usd/test_128_888.bin");
    lv_obj_set_pos(img_var, 0, 0);

    while (true) {
      pros::delay(20);
    }
}

This was the image I used for testing, converted from png using the old converter.

test_128_888.bin.zip (1.7 KB)

Image should be in root of SD card, the /usd path is a PROS thing.

Update 9/27/2019
For PROS kernel 3.2.0, which contains lvgl version 5.3, the new (or is that current) image converter should be used.
Select “True color with Alpha” for the color format
Select “Binary RGB888” for the output format

5 Likes

To be fair, the PROS team would have a much easier time updating LVGL (and adding many other features users are asking for) if it was possible for external contributors to make and test changes on their own. Unfortunately, this isn’t really possible right now because the SDK is only provided to select developers under an NDA. Is there any chance we could see this change in the future?

7 Likes

It worked. Thanks a lot. I once suspected that i have to create the driver, but i didnt. Anyways, thanks!

However, my picture did not work. Is there a size limit?

I think you can download or clone the pros api from github

Yup, you can clone the PROS kernel from their github repository and read through it all you want, and that’s great. I am thrilled the PROS team was able to open source the PROS 3 kernel. However, if you actually want to contribute to the project by either make improvements to it or fixing bugs, there is no proper way to build a custom version to test with because, “The PROS 3 kernel depends on VEX’s proprietary Software Development Kit (SDK), which is not publicly available.” (from the bottom of their readme).

1 Like

with help of @jpearman, I have figured out how to convert an image. use https://littlevgl.com/image-to-c-array-old. Choose none for transparency and RGB888. Using a jpeg file to convert works best. other file types might be distorted in color or some other way. Also the size limit of a picture is around 420x 390 pixels

2 Likes