Set uint32_t image buffer to lv_img object

Description

How can I convert uint32_t image_buffer so that i could set it as image src into lv_img_set_src(img, src)

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

Kendryte K210 processor, KD233 dev board

What LVGL version are you using?

V7.0

What do you want to achieve?

I’m trying to preview my camera feed in to lv_img object. I hope i have chosen the right UI object for my purpose. basically lv_img_set_src will loop with the camera feed.

Code to reproduce/What have you tried so far?

I have tried below code and various other attempts with no luck. It works fine if I write image_buffer directly to LCD without LVGL.


lv_obj_t * img1 = lv_img_create(lv_scr_act(), NULL);

static void lcd_show_camera_image(uint32_t image_buffer, int width, int height, uint32_t ai_reg_buf, uint32_t ai_green_buf, uint32_t ai_blue_buf)
{

lv_img_dsc_t img_bg = {
            .header.always_zero = 0,
            .header.w = width,
            .header.h = height,
            .data_size = width * height * LV_COLOR_SIZE / 8,
            .header.cf = LV_IMG_CF_TRUE_COLOR,
            .data = &image_buffer,
            };

    lv_img_set_src(img1, img_bg);
}

Any leads or guidance would be really appreciated. Thank you!

1 Like

Hi @prasad,

Looking at your code snippet, I am not sure the image buffer address is being assigned correctly.

If you are passing a uint32_t I assume this is the actual address of the buffer? If so you don’t want to assign the address of this variable to the data part of the structure. I would expect it to be something like:

.data = (uint8_t*)image_buffer;

instead.

I hope that makes sense.

Kind Regards,

Pete

Hi @pete-pjb,

Thanks for the response. Yes, You are right. this is the actual address of the buffer. I just realized the above struct is not accepted for lv_img_set_src to begin with. Instead, I tried to pass the pixel data directly into lv_img_set_src like below,

lv_img_set_src(img1, (uint8_t*) image_buffer);

However, It did display some gibberish text on the screen(See the attached image). I’m not sure this buffer holds the required correct image data format. How can I check the content of image_buffer in a meaningful way? to make sure it is in an acceptable image data format.

Sending image_buffer to LCD directly using below code works just fine,

static void nt35310_tft_write_word(uint32_t *data_buf, uint32_t length)
    {
        nt35310_set_dcx_data();
        spi_init(s_nt35310_config.spi_device_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);

        spi_init_non_standard(s_nt35310_config.spi_device_num, 0/*instrction length*/, 32/*address length*/, 0/*wait cycles*/,
                              SPI_AITM_AS_FRAME_FORMAT/*spi address trans mode*/);
        spi_send_data_normal_dma(s_nt35310_config.dma_channel_num, s_nt35310_config.spi_device_num, nt35310_get_spi_select_by_function(s_nt35310_config.spi_cs),data_buf, length, SPI_TRANS_INT);
    }

Thanks & Regards,
Prasad.

Hi @prasad ,

I’m currently looking into how best to get the data into the LVGL image and will try and get back to you about it. In the mean time can you look at the following questions please?

Do you have any information about which image format your camera is delivering the data to the buffer in?

Can you confirm you can show a simple LVGL screen with a button or something to demonstrate your drivers are working correctly with LVGL?

Kind Regards,

Pete

Hi @pete-pjb,

I’m using OV5640 image sensor. I’m pretty new to this camera module, however I believe it outputs 8-bit RGB raw. I’m running their example configuration. I have attached the config file for your reference if required. ov5640cfg.h (8.1 KB)

Also, I can confirm that the LVGL implementation is working perfectly. As I could run any example given in the lv_examples repository.

Here I’m running lv_ex_img example with my setup.

Thanks and Regards,
Prasad.

Hi @prasad ,

Okay it looks like the camera buffer should be RGB888 format it may or may not work with LVGL directly but we should try and get at least something to display first and see whether it needs reformatting later…

I think something along these lines should work which is pretty similar to your first posting…

static lv_obj_t * img1 = lv_img_create(lv_scr_act(), NULL);

static void lcd_show_camera_image(uint32_t image_buffer, int width, int height )
{

    static lv_img_dsc_t img_bg = {
            .header.always_zero = 0,
            .header.w = width,
            .header.h = height,
            .data_size = width * height * LV_COLOR_SIZE / 8,
            .header.cf = LV_IMG_CF_TRUE_COLOR,
            .data = (uint8_t*)image_buffer
            };

    lv_img_set_src(img1, &img_bg);
}

The assumption for the above code is the image buffer is global or a reserved area for dma.
Note also the img_bg & img1 variables need to be static so they are always available and not destroyed when exiting the function. Also lv_img_set_src() function needs the address of the img_bg variable passed hence the ‘&’ prefix in the call.

I would give this a try and see what happens, I would expect something on the screen even if it’s not the correct image.

Kind Regards,

Pete

2 Likes

HI @pete-pjb,

That was it. It worked perfectly. Thank you very much for the help Pete.

See the attached image of working setup.

I have tweaked the code a little bit, but that is essentially the same thing you suggested. See below,

static lv_obj_t * img1 = lv_img_create(lv_scr_act(), NULL);
static uint32_t image_buffer_strong_ref;
static lv_img_dsc_t img_bg;

static void lcd_show_camera_image(uint32_t image_buffer, int width, int height)
{
   image_buffer_strong_ref = image_buffer;

   img_bg.header.always_zero = 0;
   img_bg.header.w = width;
   img_bg.header.h = height;
   img_bg.data_size = width * height * LV_COLOR_SIZE / 8;
   img_bg.header.cf = LV_IMG_CF_TRUE_COLOR;
   img_bg.data = (uint8_t *)image_buffer_strong_ref;
            
   lv_img_set_src(img1, &img_bg);

}

Thanks & Regards,
Prasad.

1 Like

Hi @prasad ,

No worries, glad it’s working for you now. :smile:

Kind Regards,

Pete.

1 Like