目的
学习canvas的使用。
功能描述
用户想绘制一个自己的图片。这个图片了有大小要求,可以调配画布中各个颜色,如果单片机操作某个像素或者三色的led灯一样,控制各个像素的颜色。
ui提供了一个画布的控件。用户可以在上面可以设计自己想要的图形、文字。设计显示的风格,并对这些设计的图案可以切换任何角度。
控件使用步骤以及相关函数描述
使用步骤
首先创建一个canvas对象,然后给其绑定一个buffer。此buffer决定其在窗口中,画布的有效像素大小,操作此buffer,就是操作画布图案。
配置画布显示的位置,设计画布中的图案风格,如文字颜色,图案的阴影,边框大小,边框颜色等。
函数描述
-
模块创建
lv_obj_t *lv_canvas_create(lv_obj_t *par, constlv_obj_t *copy)
-
绑定buffer
void lv_canvas_set_buffer(lv_obj_t *canvas, void *buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
x,y:为宽高;
cf:为颜色格式
void lv_canvas_copy_buf(lv_obj_t *canvas, const void *to_copy, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h)//拷贝对应画布中对应区域的像素数据
-
设置画布中某个像素点
//配置某个像素的颜色
void lv_canvas_set_px(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)
x,y:像素点坐标;
c:要配置颜色
lv_color_tlv_canvas_get_px(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y)
-
设置画布内容风格
void lv_canvas_set_style(lv_obj_t *canvas, lv_canvas_style_ttype, const lv_style_t *style)
-
其他
void lv_canvas_fill_bg(lv_obj_t *canvas, lv_color_t color)//画布填充一种颜色
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_style_t *style)//指定位置绘制一个指定大小风格方形
void lv_canvas_draw_text(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, const lv_style_t *style, const char *txt, lv_label_align_t align)//指定位置绘制指定小风格的文字
void lv_canvas_draw_img(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, const void *src, const lv_style_t *style)//指定位置绘制一个指定风格图像
src:为图像源,详细可见image控件文档
void lv_canvas_draw_polygon(lv_obj_t *canvas, const lv_point_t *points, uint32_t point_cnt, const lv_style_t *style)//绘制多边形
points:为多边形的点
cnt:为点的个数
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_style_t *style)//绘制圆
x,y :圆心;
r:为半径;
start_angle:起始角度;
end_angle:结束角度
style:风格
void lv_canvas_draw_line(lv_obj_t *canvas, const lv_point_t *points, uint32_t point_cnt, const lv_style_t *style)//绘制线
lv_img_dsc_t *lv_canvas_get_img(lv_obj_t *canvas)//获取画布的图形
void lv_canvas_rotate(lv_obj_t *canvas, lv_img_dsc_t *img, int16_t angle, lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y)//旋转图形
需要注意的是,旋转的是和画布相关的buffer中的内容,而不是buffer自身。buffer不变,只是内容按照一定的角度重新存在buffer中。
案例和代码
实现一个canvas案例,在上面绘制一幅图,采用一个按钮事件的方式,每单击一次,图形会旋转5度。
#include "ljy_canvas.h"
#include "lvgl/lvgl.h"
#define CANVAS_WIDTH 320
#define CANVAS_HEIGHT 200
#define TEST_ROTATE 0
static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];//画布对应的缓存,按照配置颜色格式描述画布的颜色
static lv_color_t cbuf_tmp[CANVAS_WIDTH * CANVAS_HEIGHT];//显示图像的原始缓存
static lv_img_dsc_t img;//要显示图像
static lv_obj_t * canvas;
static void BttonEventCb(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_CLICKED) {//点击事件
static short int arc_ang = 0;
lv_canvas_fill_bg(canvas, LV_COLOR_SILVER);//重新刷一次图像
//实际将img中的数据旋转对应角度后,存放在canvas绑定的buffer中
lv_canvas_rotate(canvas, &img,arc_ang, 0, 0, CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2);//从0,0开始放置围绕中心旋转的图像数据
arc_ang += 5;
if(arc_ang == 360)arc_ang = 0;
printf("current rotate ang is %d\n",arc_ang);
}
}
void DrawCanvas()
{
//1. 创建画布
canvas = lv_canvas_create(lv_scr_act(), NULL);
lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);//设置画布对应像素大小,颜色格式=
lv_obj_align(canvas, NULL, LV_ALIGN_CENTER, 0, 0);//显示位置
lv_canvas_fill_bg(canvas, LV_COLOR_SILVER);//填充颜色
//2. 画布风格
static lv_style_t style;
lv_style_copy(&style, &lv_style_plain);
style.body.main_color = LV_COLOR_RED;//主颜色
style.body.grad_color = LV_COLOR_MAROON;//渐变颜色,栗色
style.body.radius = 4;//圆弧半径
style.body.border.width = 2;//边界宽度
style.body.border.color = LV_COLOR_PURPLE;//边界颜色
style.body.shadow.color = LV_COLOR_WHITE;//影子颜色
style.body.shadow.width = 4;//
style.line.width = 2;//画布中线的宽度
style.line.color = LV_COLOR_BLACK;//线条为黑色
style.text.color = LV_COLOR_BLUE;
//3.按照此风格绘制一个方形
lv_canvas_draw_rect(canvas, CANVAS_WIDTH >> 1, CANVAS_HEIGHT >> 1, 50, 30, &style); //在画布中间绘制一个方形,宽50,高30
//4. 按照像素的方式绘制一片区域的杨素
int i = 0;int j = 0;
for(i = 0; i < 100; i++){
for(j = 0; j < 10; j++){
lv_canvas_set_px(canvas,i,j,LV_COLOR_GREEN);
}
}
//5.在当前画布中实现一个img
memcpy(cbuf_tmp, cbuf, sizeof(cbuf_tmp));//这里的cbuf为参考图像缓存
img.data = (void *)cbuf_tmp;
img.header.cf = LV_IMG_CF_TRUE_COLOR;//颜色格式rgb
img.header.w = CANVAS_WIDTH;//图形宽高
img.header.h = CANVAS_HEIGHT;
//6.创建事件按钮
lv_obj_t *btn = lv_btn_create(lv_scr_act(), NULL);
lv_obj_align(btn,canvas,LV_ALIGN_OUT_BOTTOM_MID,0,10);
lv_obj_set_size(btn,60,40);
lv_obj_set_event_cb(btn, BttonEventCb);
}
总结