目录
Canvas 继承自Image,用户可以在其中绘制任何内容。由lv_canvas_create创建。
lv_obj_t* canvas = lv_canvas_create(lv_scr_act());
画布需要先分配足够空间的缓冲区来存储绘制的图像
void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
buffer必须是一个静态缓冲区,大小是(lv_img_cf_get_px_size(cf) * w) / 8 * h),可以通过lv_mem_alloc()分配或静态数组或RAM(SRAM)的地址。
w,h是画布的长宽
cf是画布的图像格式
static lv_color_t canvasBuf[(32 * 128) / 8 * 128];
lv_canvas_set_buffer(canvas, canvasBuf, 128, 128, LV_IMG_CF_TRUE_COLOR);
此时由于buffer中的数据是全0,显示出来的就是黑色方块。
所以,对画布的操作其实是对buffer的处理。
uint16_t x, y;
for (x = 0; x < 128; x++)
{
for (y = 0; y < 128; y++)
{
canvasBuf[x * 128 + y] = lv_color_hex(0xFF0000);
}
}
可以通过函数lv_canvas_fill_bg设置画布的背景颜色。
void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa)
例如:
lv_canvas_fill_bg(canvas, lv_color_hex(0xFF0000), LV_OPA_50);
1. 绘制
1.1 画点
static inline void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)
例如
lv_canvas_set_px(canvas, 64, 64, lv_color_hex(0xFFFFFF));
1.2 画线
void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, const lv_draw_line_dsc_t * draw_dsc)
points是线的端点坐标,point_cnt是端点数量,draw_dsc是线的样式。
const lv_point_t linePoint[2] = { {0,0}, {128, 128} };
lv_draw_line_dsc_t line_dsc;
lv_draw_line_dsc_init(&line_dsc);
lv_canvas_draw_line(canvas, linePoint, 2, &line_dsc);
1.2 画矩形框
void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, const lv_draw_rect_dsc_t * draw_dsc)
x,y,w,h是矩形框的坐标和长宽,而draw_dsc是矩形框的样式。
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
lv_canvas_draw_rect(canvas, 0, 0, 64, 64, &rect_dsc);
1.3 画多边形
void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, const lv_draw_rect_dsc_t * draw_dsc)
points是多边形的端点坐标,point_cnt是端点数量,draw_dsc是多边形的样式。
const lv_point_t polygonPoint[3] = { {0, 0}, {0, 64} , {64, 64} };
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
lv_canvas_draw_polygon(canvas, polygonPoint, 3, &rect_dsc);
1.4 画圆弧
void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle, int32_t end_angle, const lv_draw_arc_dsc_t * draw_dsc)
x,y是圆弧的圆心坐标,r是圆弧的半径,start_angle和end_angle是起始角度,draw_dsc是圆弧的样式。
lv_draw_arc_dsc_t arc_dsc;
lv_draw_arc_dsc_init(&arc_dsc);
lv_canvas_draw_arc(canvas, 64, 64, 32, 0, 45, &arc_dsc);
1.5 添加字符串
void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, lv_draw_label_dsc_t * draw_dsc, const char * txt);
x,y是坐标,max_w是字符串的最大宽度,draw_dsc是字符串的样式,txt是字符串。
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_canvas_draw_text(canvas, 0, 0, 128, &label_dsc, "Hello");
1.6 添加图像
void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, const lv_draw_img_dsc_t * draw_dsc);
x,y是坐标,src是图像的源,可以是文件、结构体指针、Symbol,draw_dsc是图像的样式。
lv_draw_img_dsc_t img_dsc;
lv_draw_img_dsc_init(&img_dsc);
lv_canvas_draw_img(canvas, 30, 30, &imgFan, &img_dsc);
2. 糊化
在画布上可以应用糊化:
void lv_canvas_blur_hor(lv_obj_t * canvas, const lv_area_t * area, uint16_t r);
void lv_canvas_blur_ver(lv_obj_t * canvas, const lv_area_t * area, uint16_t r);
area是糊化的范围大小,NULL表示整个画布,r是糊化的程度,值越大意味着毛刺越强。
lv_area_t bur_area;
uint16_t bur_r = 10;
bur_area.x1 = 30;
bur_area.y1 = 30;
bur_area.x2 = 50;
bur_area.y2 = 50;
lv_canvas_blur_hor(canvas, &bur_area, bur_r);
后面2张图是lv_canvas_blur_ver和bur_r = 50对比。
3. 变换
void lv_canvas_transform(lv_obj_t * obj, lv_img_dsc_t * src_img, int16_t angle,
uint16_t zoom, lv_coord_t offset_x, lv_coord_t offset_y,
int32_t pivot_x, int32_t pivot_y, bool antialias)
用于旋转和/或缩放图像的图像并将结果存储在画布上。
src_img的类型是lv_img_dsc_t,说明只有结构体指针能使用这种方式。
而offset_x和offset_y是对应画布原点的偏移。
lv_canvas_transform(canvas, (lv_img_dsc_t *) &imgFan,
450, 256, 20, 20, 25, 25, false);
这里有个问题,Alpha通道没了。