How to create a canvas for alpha masking?

I would like to create a canvas for alpha masking,
and try to create masking by draw a circle on it.
But the result of the circle on this canvas is not look like circle .

My code for testing

// Environment:
// 1. TFT 16 bit color 240x240
// 2. ESP32
// 3. littlevgl 6.0

#define CANVAS_W 240
#define CANVAS_H 240

// Create canvas_alpha with ALPHA 8 BIT
lv_color8_t* canvas_alpha_buf = (lv_color8_t*) malloc(LV_CANVAS_BUF_SIZE_ALPHA_8BIT(CANVAS_W,CANVAS_H));
lv_obj_t* canvas_alpha = lv_canvas_create(lv_scr_act(), NULL);
lv_canvas_set_buffer(canvas_alpha, canvas_alpha_buf, CANVAS_W,CANVAS_H, LV_IMG_CF_ALPHA_8BIT);
lv_canvas_fill_bg(canvas_alpha, LV_COLOR_BLACK);

// Draw Circle on canvas_alpha
lv_color_t cir_color = LV_COLOR_WHITE;
int center_x = 120;
int center_y = 120;
int radius = 50;

static lv_style_t style;
lv_style_copy( &style, &lv_style_plain);
style.body.main_color = cir_color;
style.body.grad_color = cir_color;
style.body.radius = LV_RADIUS_CIRCLE;
lv_canvas_draw_rect(canvas_alpha, center_x-radius, center_y-radius, 2 * radius, 2 * radius, &style);

// View the canvas_alpha’s data on the serial monitor
lv_canvas_ext_t * ext_canvas_alpha = (lv_canvas_ext_t* ) lv_obj_get_ext_attr(canvas_alpha);
uint8_t * alphas = ( uint8_t * ) ext_canvas_alpha->dsc.data;
for(int j=0;j < CANVAS_H; ++j){
for(int i=0; i <CANVAS_W; ++i){
uint8_t a = alphas[ i+ CANVAS_W*j ];
if( a ) printf("%02x", a);
else print(" “);
}
printf(”\n");
}

How to create a canvas for alpha masking?
Or any advice for creating circle masking on the canvas_alpha?

Thank you.

Are you trying to put a hole in your canvas area that lets you see through to other objects?

If so, I don’t think that behavior is supported at the moment.

You can use LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED color format. Drawing with LV_COLRO_TRANSP will result in transparent pixels.

This code worked for me:

#define CANVAS_W 240
#define CANVAS_H 240


    // Create canvas_alpha with ALPHA 8 BIT
    lv_color_t * canvas_buf = (lv_color_t*) malloc(LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(CANVAS_W,CANVAS_H));
    lv_obj_t* canvas = lv_canvas_create(lv_scr_act(), NULL);
    lv_canvas_set_buffer(canvas, canvas_buf, CANVAS_W,CANVAS_H, LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED);

    lv_canvas_fill_bg(canvas, LV_COLOR_BLACK);

    // Draw Circle on canvas_alpha
    lv_color_t cir_color = LV_COLOR_TRANSP;
    int center_x = 120;
    int center_y = 120;
    int radius = 50;

    static lv_style_t style;
    lv_style_copy( &style, &lv_style_plain);
    style.body.main_color = cir_color;
    style.body.grad_color = cir_color;
    style.body.radius = LV_RADIUS_CIRCLE;
    lv_canvas_draw_rect(canvas, center_x-radius, center_y-radius, 2 * radius, 2 * radius, &style);

I’ve pushed a fix to master to disable anti-aliasing when drawing with LV_COLOR_TRANSP.

I’ll update the docs the mention that the lv_canvas_draw functions can be used only with LV_IMG_CF_TRUE_COLOR_... color format.

1 Like