Thank you for your links, I see you are using different porch & clock rate settings(do you have a souce for these?), I will explore this further at some point.
I will think about the blur issue, it will be easier for me to comment once I have my hardware working correctly.
I will come back to you here once I have thought some more. If you try anything in the meantime feel free to post your findings here.
It actually just takes a picture of the lv_obj_t passed to the function, which in the test is just the text area, it blurs it, then puts it on the canvas at the same coordinates as the original object.
I have been thinking if would be possible to use a very smaller buffer like 100 x 100 and then create the blurred image on the canvas step by step
takes a snapshot of the very top of the area that will be blurred blurs it in the canvas now empty the buffer and the snapshot to take a new one of 100 pixels for example under the first snapshot and keep this cycle until it had passed though all the canvas
just for documenting i have made this blur function that gives a better appearance result than the actual LVGL but also have a strange bug that i cant use a radius value bigger than 5
void lv_canvas_box_blur(lv_obj_t *obj, const lv_area_t *area, uint16_t r) {
LV_ASSERT_OBJ(obj, MY_CLASS);
if (r == 0) return;
lv_canvas_t *canvas = (lv_canvas_t *)obj;
lv_area_t a;
if (area) {
lv_area_copy(&a, area);
if (a.x1 < 0) a.x1 = 0;
if (a.y1 < 0) a.y1 = 0;
if (a.x2 > canvas->dsc.header.w - 1) a.x2 = canvas->dsc.header.w - 1;
if (a.y2 > canvas->dsc.header.h - 1) a.y2 = canvas->dsc.header.h - 1;
} else {
a.x1 = 0;
a.y1 = 0;
a.x2 = canvas->dsc.header.w - 1;
a.y2 = canvas->dsc.header.h - 1;
}
lv_color_t color = lv_obj_get_style_img_recolor(obj, LV_PART_MAIN);
bool has_alpha = lv_img_cf_has_alpha(canvas->dsc.header.cf);
lv_coord_t x, y;
// Horizontal blur
for (y = a.y1; y <= a.y2; y++) {
for (x = a.x1; x <= a.x2; x++) {
uint32_t r_sum = 0;
uint32_t g_sum = 0;
uint32_t b_sum = 0;
uint32_t a_sum = 0;
uint32_t pixel_count = 0;
for (lv_coord_t i = x - r; i <= x + r; i++) {
if (i >= a.x1 && i <= a.x2) {
lv_color_t c = lv_img_buf_get_px_color(&canvas->dsc, i, y, color);
if (has_alpha) {
lv_opa_t opa = lv_img_buf_get_px_alpha(&canvas->dsc, i, y);
a_sum += opa;
}
r_sum += c.ch.red;
g_sum += c.ch.green;
b_sum += c.ch.blue;
pixel_count++;
}
}
lv_color_t blurred_color;
blurred_color.ch.red = r_sum / pixel_count;
blurred_color.ch.green = g_sum / pixel_count;
blurred_color.ch.blue = b_sum / pixel_count;
if (has_alpha) {
lv_opa_t blurred_alpha = a_sum / pixel_count;
blurred_color.full = (blurred_alpha << 24) | (blurred_color.full & 0x00FFFFFF);
}
lv_img_buf_set_px_color(&canvas->dsc, x, y, blurred_color);
}
}
// Vertical blur
for (x = a.x1; x <= a.x2; x++) {
for (y = a.y1; y <= a.y2; y++) {
uint32_t r_sum = 0;
uint32_t g_sum = 0;
uint32_t b_sum = 0;
uint32_t a_sum = 0;
uint32_t pixel_count = 0;
for (lv_coord_t j = y - r; j <= y + r; j++) {
if (j >= a.y1 && j <= a.y2) {
lv_color_t c = lv_img_buf_get_px_color(&canvas->dsc, x, j, color);
if (has_alpha) {
lv_opa_t opa = lv_img_buf_get_px_alpha(&canvas->dsc, x, j);
a_sum += opa;
}
r_sum += c.ch.red;
g_sum += c.ch.green;
b_sum += c.ch.blue;
pixel_count++;
}
}
lv_color_t blurred_color;
blurred_color.ch.red = r_sum / pixel_count;
blurred_color.ch.green = g_sum / pixel_count;
blurred_color.ch.blue = b_sum / pixel_count;
if (has_alpha) {
lv_opa_t blurred_alpha = a_sum / pixel_count;
blurred_color.full = (blurred_alpha << 24) | (blurred_color.full & 0x00FFFFFF);
}
lv_img_buf_set_px_color(&canvas->dsc, x, y, blurred_color);
}
}
lv_obj_invalidate(obj);
}
I watched your discussion process, and then tried to simulate it in the simulator myself. There are logs in code execution,but I did not achieve the effect. Referring to the function :
“lv_canvas_box_blur(lv_obj_t *obj, const lv_area_t *area, uint16_t r)”
lv_obj_t *ta;
ta = lv_textarea_create(ui->scr_main);
lv_textarea_set_text( ta, “Some Test in a box!”);
lv_obj_set_size(ta, 200, 150);
lv_obj_align(ta, LV_ALIGN_TOP_LEFT, 30, 30);
lv_obj_t * canvas = lv_canvas_create( ui->scr_main);