Draw something on top of lv_image

Description

I have drawn a snapshot of google maps on my screen using lv_image widget.
Now I would like to draw some red circles on my map to indicate the location on the map.

Do you have any advice on how to do this ? Which widget should I use ?

Should I modify somehow the existing image or draw something on top of it ?

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

EK-RA8D1

What LVGL version are you using?

v9.1.1

Thanks and regards

Hello, AZ_Renesas, funny to see you here as well as on the Renesas Community…

Anyway, I figure this is what you’re looking for: Canvas (lv_canvas) — LVGL documentation
Another option is to draw the circles on the top layer by setting lv_layer_top() as their parents upon creation, but then you cannot move the image around with the circles on top.

For drawing circles, the easiest option would be to create an empty object and setting it’s radius style to LV_RADIUS_CIRCLE and the border width/color styles accordingly.

Hope this helps

Hi Tinus,
Yes, I’m just on the other side of the table now :slight_smile:

So my idea was to load an image on the canvas and then change the color of some pixels.

    LV_IMAGE_DECLARE(office);

    // Create object to hold the frame
    lv_obj_t *iframe = lv_obj_create(lv_screen_active());
    lv_obj_set_size(iframe, 420, 820);
    lv_obj_align(iframe, LV_ALIGN_CENTER, 0, 0);
    // add scroll bars
    lv_obj_add_flag(iframe, LV_OBJ_FLAG_SCROLLABLE);


    // Add canvas to frame object
    lv_obj_t * canvas = lv_canvas_create(iframe);
    lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);
    lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);
    lv_obj_center(canvas);

    // Add image to canvas
    lv_obj_t *img1 = lv_image_create(canvas);
    lv_image_set_src(img1, &office);
    lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);

    uint32_t x;
    uint32_t y;
    for(x = 50 ; x < 100; x++)
    {
        for(y = 50 ; y <50 ; y++)
        {
            lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_RED), LV_OPA_COVER);
        }
    }
    }

However I see no red pixels on my screen. Can you see anything wrong ?

Thanks a lot.

Hello,

I must admit I have never used the canvas before, but looking at the examples on the documentation, I believe you will have to add the image to the canvas as a layer: Canvas (lv_canvas) — LVGL documentation (links to example).

    lv_layer_t layer;
    lv_canvas_init_layer(canvas, &layer);

    LV_IMAGE_DECLARE(img_star);
    lv_draw_image_dsc_t dsc;
    lv_draw_image_dsc_init(&dsc);
    dsc.src = &img_star;

    lv_area_t coords = {10, 10, 10 + img_star.header.w - 1, 10 + img_star.header.h - 1};

    lv_draw_image(&layer, &dsc, &coords);

    lv_canvas_finish_layer(canvas, &layer);

I believe after this step you may be able to use lv_canvas_set_px() and actually see your changes, currently you have the image as a child of the canvas object which means it overlaps the drawing area of the canvas, your pixels are probably just not visible right now.

For testing purposes you may want to try not calling lv_image_create() at all and seeing if lv_canvas_set_px()does what you expect.

Kind regards,
Tinus

As far as I understand you can simple draw base object with rounded corners, red border of none-zero width and transparent background. You just need to create an image first and then an object to control their location

lv_obj_t * img = lv_image_create(parent);
...
lv_obj_t * circle = lv_obj_create(parent);

after that change position of base object to move it

if you need filled circles - use colored background