Text overlay over image has some artefacts

Hi there,
i read a lot of threads that handle similar topics but unfortunately I did not find a solution for my issue yet.


I have two different framebuffers, one with an image that may change unpredictably and an other FB that should be filled with an graphical overlay created with lvgl.
Alpha-blending of both framebuffers is handled by HW.

As you can see in the attached picture the text that lvgl produces has some ugly artifacts around the single characters. The blue/yellow/magenta color is part of the image layer.
If the image layer is black, the grey characters are looking pretty well.
The attached image is captured with blend mode “LV_BLEND_MODE_NORMAL”.
Other blend modes produce better characters but the characters get black instead of grey.

I read here that opacity may only be 0% or 100% for images. I don’t know if this is also valid for characters?

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

Arm Cortex A53 Quad Core
Gnu GCC compiler
Enough RAM for at least 4 Framebuffers
Display Resolution 1024x768

What LVGL version are you using?


What do you want to achieve?

Show characters and bitmaps as overlay without artifacts and semi-transparency.

What have you tried so far?

#define LV_COLOR_DEPTH 32
different blend modes:
LV_BLEND_MODE_NORMAL, /**< Simply mix according to the opacity value*/
LV_BLEND_MODE_ADDITIVE, /**< Add the respective color channels*/
LV_BLEND_MODE_SUBTRACTIVE,/**< Subtract the foreground from the background*/
LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/
LV_BLEND_MODE_REPLACE, /**< Replace background with foreground in the area*/

Code to reproduce

#define LV_COLOR_DEPTH 32

    ui_Screen = lv_obj_create(NULL);

    lv_obj_set_style_bg_color(ui_Screen, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_Screen, 0, LV_PART_MAIN | LV_STATE_DEFAULT);

    ui_test = lv_label_create(ui_Screen);

    lv_label_set_text(ui_test, "TEST");
    lv_label_set_recolor(ui_test, "true");

    lv_obj_set_style_text_color(ui_test, lv_color_hex(0x808080), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_opa(ui_test, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_font(ui_test, &lv_font_montserrat_30, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_blend_mode(ui_test, LV_BLEND_MODE_NORMAL, LV_PART_MAIN | LV_STATE_DEFAULT);

Screenshot and/or video


Additionally I tried to set the following in the display driver:

static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t  disp_drv;
static lv_color_t buf1[DISP_HOR_RES*DISP_VER_RES];
static lv_color_t buf2[DISP_HOR_RES*DISP_VER_RES];

lv_disp_draw_buf_init(&draw_buf, buf1, buf2, DISP_HOR_RES*DISP_VER_RES);  /*Initialize the display buffer.*/
disp_drv.draw_buf = &draw_buf;          /*Set an initialized buffer*/
disp_drv.flush_cb = my_disp_flush;        /*Set a flush callback to draw to the display*/
disp_drv.monitor_cb = monitor_cb;

disp_drv.screen_transp = 1;
disp_drv.full_refresh = true;
lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/

The result was a fully transparent screen without any content because in

draw_buf_flush(lv_disp_t * disp)

the active draw buffer is cleared with


before the flush callback is called.

If I call the flush callback at first and lv_memset_00 afterwards everything looks great and the artifacts are gone.

May this be some kind of bug or did I just understand something wrong?

Hi @kisvegabor ,

from my point of view my issue is solved but I need to change the function draw_buf_flush in lv_refr.c locally.

The lines 1192 to 1210 need to moved down to line 1228 (line numbers refer to lvgl tag 8.3.0).
That means the flushing callback is called first.
After that, while(draw_buf->flushing) waits for the flushing to be finished before the active buffer is cleared.

What do you think?

Best regards


It’s great that you could find a solution.
Can you send a pull request with the suggested change? Just to be sure we are talking about the same thing.