Canvas (lv_canvas)

概述

画布继承自图像,用户可以在其上绘制任何内容。 可以使用 LVGL 的绘图引擎绘制矩形、文本、图像、线条和弧线。 此外,还可以应用“效果”,例如旋转、缩放和模糊。

部件和样式

LV_PART_MAIN 使用典型的矩形样式属性和图像样式属性。

用法

缓冲区

画布需要一个缓冲区来存储绘制的图像。 可以使用 lv_canvas_set_buffer(canvas, buffer, width, height, LV_IMG_CF_...) 为画布分配缓冲区。 其中,buffer 是一个静态缓冲区(不仅仅是局部变量),用于保存画布的图像。 例如: static lv_color_t buffer[LV_CANVAS_BUF_SIZE_TRUE_COLOR(width, height)]LV_CANVAS_BUF_SIZE_... 宏可以帮助确定不同颜色格式下缓冲区的大小。

画布支持所有内置的颜色格式,例如 LV_IMG_CF_TRUE_COLORLV_IMG_CF_INDEXED_2BIT。 完整列表请参阅颜色格式部分。

索引颜色

对于 LV_IMG_CF_INDEXED_1/2/4/8 颜色格式,需要使用 lv_canvas_set_palette(canvas, 3, LV_COLOR_RED) 初始化调色板。它将索引为 index=3 的像素设置为红色。

绘图

要在画布上设置像素的颜色,可以使用 lv_canvas_set_px_color(canvas, x, y, LV_COLOR_RED)。 对于 LV_IMG_CF_INDEXED_... 格式,需要将颜色的索引作为颜色传递。 例如:lv_color_t c; c.full = 3;

对于 LV_IMG_CF_TRUE_COLOR_ALPHALV_IMG_CF_ALPHA_... 格式,可以使用 lv_canvas_set_px_opa(canvas, x, y, opa) 设置像素的不透明度。

使用 lv_canvas_fill_bg(canvas, LV_COLOR_BLUE, LV_OPA_50) 可以将整个画布填充为 50% 不透明度的蓝色。需要注意的是,如果当前颜色格式不支持颜色(例如 LV_IMG_CF_ALPHA_2BIT),颜色将被忽略。 类似地,如果不支持不透明度(例如 LV_IMG_CF_TRUE_COLOR),不透明度也将被忽略。

可以使用 lv_canvas_copy_buf(canvas, buffer_to_copy, x, y, width, height) 将像素数组复制到画布上。 缓冲区和画布的颜色格式需要匹配。

要在画布上绘制内容,可以使用以下函数:

  • lv_canvas_draw_rect(canvas, x, y, width, heigth, &draw_dsc)

  • lv_canvas_draw_text(canvas, x, y, max_width, &draw_dsc, txt)

  • lv_canvas_draw_img(canvas, x, y, &img_src, &draw_dsc)

  • lv_canvas_draw_line(canvas, point_array, point_cnt, &draw_dsc)

  • lv_canvas_draw_polygon(canvas, points_array, point_cnt, &draw_dsc)

  • lv_canvas_draw_arc(canvas, x, y, radius, start_angle, end_angle, &draw_dsc)

draw_dsc 是一个 lv_draw_rect/label/img/line/arc_dsc_t 变量,应该首先使用 lv_draw_rect/label/img/line/arc_dsc_init() 之一进行初始化,然后根据需要修改颜色和其他值。

绘图函数可以绘制到任何颜色格式。例如,可以在 LV_IMG_VF_ALPHA_8BIT 画布上绘制文本,并在后续将结果图像用作绘图遮罩

变换

可以使用 lv_canvas_transform() 旋转和/或缩放图像,并将结果存储在画布上。 该函数需要以下参数:

  • canvas 指向画布对象的指针,用于存储变换结果。

  • img pointer 指向要变换的图像描述符的指针。也可以是另一个画布的图像描述符(lv_canvas_get_img())。

  • angle 旋转角度(0..3600),0.1 度分辨率。

  • zoom 缩放因子(256: 无缩放,512: 双倍大小,128: 半大小)。

  • offset_x X 偏移量,用于指定结果数据在目标画布上的位置。

  • offset_y Y 偏移量,用于指定结果数据在目标画布上的位置。

  • pivot_x 旋转的 X 轴中心点。相对于源画布。设置为 源宽度 / 2 以绕中心旋转。

  • pivot_y 旋转的 Y 轴中心点。相对于源画布。设置为 源高度 / 2 以绕中心旋转。

  • antialias 是否在变换过程中应用抗锯齿。开启后效果更好但速度较慢。

注意,画布不能在自身上旋转。需要一个源画布和目标画布或图像。

模糊

可以使用 lv_canvas_blur_hor(canvas, &area, r) 水平模糊画布的指定区域,或使用 lv_canvas_blur_ver(canvas, &area, r) 垂直模糊。 r 是模糊半径(值越大模糊越强)。area 是需要应用模糊的区域(相对于画布解释)。

事件

画布对象不会发送特殊事件。 发送的事件与图像相同。

了解更多关于事件的信息。

按键

此对象类型不处理任何按键

了解更多关于按键的信息。

示例

在画布上绘图并旋转

C code  

 GitHub
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES


#define CANVAS_WIDTH  200
#define CANVAS_HEIGHT  150

void lv_example_canvas_1(void)
{
    lv_draw_rect_dsc_t rect_dsc;
    lv_draw_rect_dsc_init(&rect_dsc);
    rect_dsc.radius = 10;
    rect_dsc.bg_opa = LV_OPA_COVER;
    rect_dsc.bg_grad.dir = LV_GRAD_DIR_HOR;
    rect_dsc.bg_grad.stops[0].color = lv_palette_main(LV_PALETTE_RED);
    rect_dsc.bg_grad.stops[1].color = lv_palette_main(LV_PALETTE_BLUE);
    rect_dsc.border_width = 2;
    rect_dsc.border_opa = LV_OPA_90;
    rect_dsc.border_color = lv_color_white();
    rect_dsc.shadow_width = 5;
    rect_dsc.shadow_ofs_x = 5;
    rect_dsc.shadow_ofs_y = 5;

    lv_draw_label_dsc_t label_dsc;
    lv_draw_label_dsc_init(&label_dsc);
    label_dsc.color = lv_palette_main(LV_PALETTE_ORANGE);

    static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];

    lv_obj_t * canvas = lv_canvas_create(lv_scr_act());
    lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
    lv_obj_center(canvas);
    lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);

    lv_canvas_draw_rect(canvas, 70, 60, 100, 70, &rect_dsc);

    lv_canvas_draw_text(canvas, 40, 20, 100, &label_dsc, "Some text on text canvas");

    /*Test the rotation. It requires another buffer where the original image is stored.
     *So copy the current image to buffer and rotate it to the canvas*/
    static lv_color_t cbuf_tmp[CANVAS_WIDTH * CANVAS_HEIGHT];
    memcpy(cbuf_tmp, cbuf, sizeof(cbuf_tmp));
    lv_img_dsc_t img;
    img.data = (void *)cbuf_tmp;
    img.header.cf = LV_IMG_CF_TRUE_COLOR;
    img.header.w = CANVAS_WIDTH;
    img.header.h = CANVAS_HEIGHT;

    lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);
    lv_canvas_transform(canvas, &img, 120, LV_IMG_ZOOM_NONE, 0, 0, CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, true);
}

#endif

MicroPython code  

 GitHub Simulator
_CANVAS_WIDTH = 200
_CANVAS_HEIGHT = 150
LV_IMG_ZOOM_NONE = 256

rect_dsc = lv.draw_rect_dsc_t()
rect_dsc.init()
rect_dsc.radius = 10
rect_dsc.bg_opa = lv.OPA.COVER
rect_dsc.bg_grad.dir = lv.GRAD_DIR.HOR
rect_dsc.bg_grad.stops[0].color = lv.palette_main(lv.PALETTE.RED)
rect_dsc.bg_grad.stops[1].color = lv.palette_main(lv.PALETTE.BLUE)
rect_dsc.border_width = 2
rect_dsc.border_opa = lv.OPA._90
rect_dsc.border_color = lv.color_white()
rect_dsc.shadow_width = 5
rect_dsc.shadow_ofs_x = 5
rect_dsc.shadow_ofs_y = 5

label_dsc = lv.draw_label_dsc_t()
label_dsc.init()
label_dsc.color = lv.palette_main(lv.PALETTE.YELLOW)

cbuf = bytearray(_CANVAS_WIDTH * _CANVAS_HEIGHT * 4)

canvas = lv.canvas(lv.scr_act())
canvas.set_buffer(cbuf, _CANVAS_WIDTH, _CANVAS_HEIGHT, lv.img.CF.TRUE_COLOR)
canvas.center()
canvas.fill_bg(lv.palette_lighten(lv.PALETTE.GREY, 3), lv.OPA.COVER)

canvas.draw_rect(70, 60, 100, 70, rect_dsc)
canvas.draw_text(40, 20, 100, label_dsc, "Some text on text canvas")

# Test the rotation. It requires another buffer where the original image is stored.
# So copy the current image to buffer and rotate it to the canvas

img = lv.img_dsc_t()
img.data = cbuf[:]
img.header.cf = lv.img.CF.TRUE_COLOR
img.header.w = _CANVAS_WIDTH
img.header.h = _CANVAS_HEIGHT

canvas.fill_bg(lv.palette_lighten(lv.PALETTE.GREY, 3), lv.OPA.COVER)
canvas.transform(img, 30, LV_IMG_ZOOM_NONE, 0, 0, _CANVAS_WIDTH // 2, _CANVAS_HEIGHT // 2, True)

带有色键的透明画布

C code  

 GitHub
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES

#define CANVAS_WIDTH  50
#define CANVAS_HEIGHT  50

/**
 * Create a transparent canvas with Chroma keying and indexed color format (palette).
 */
void lv_example_canvas_2(void)
{
    /*Create a button to better see the transparency*/
    lv_btn_create(lv_scr_act());

    /*Create a buffer for the canvas*/
    static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_INDEXED_1BIT(CANVAS_WIDTH, CANVAS_HEIGHT)];

    /*Create a canvas and initialize its palette*/
    lv_obj_t * canvas = lv_canvas_create(lv_scr_act());
    lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_INDEXED_1BIT);
    lv_canvas_set_palette(canvas, 0, LV_COLOR_CHROMA_KEY);
    lv_canvas_set_palette(canvas, 1, lv_palette_main(LV_PALETTE_RED));

    /*Create colors with the indices of the palette*/
    lv_color_t c0;
    lv_color_t c1;

    c0.full = 0;
    c1.full = 1;

    /*Red background (There is no dedicated alpha channel in indexed images so LV_OPA_COVER is ignored)*/
    lv_canvas_fill_bg(canvas, c1, LV_OPA_COVER);

    /*Create hole on the canvas*/
    uint32_t x;
    uint32_t y;
    for(y = 10; y < 30; y++) {
        for(x = 5; x < 20; x++) {
            lv_canvas_set_px_color(canvas, x, y, c0);
        }
    }

}
#endif

MicroPython code  

 GitHub Simulator
CANVAS_WIDTH   = 50
CANVAS_HEIGHT  = 50
LV_COLOR_CHROMA_KEY = lv.color_hex(0x00ff00)

def LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h):
    return int(((w / 8) + 1) * h)

def LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h):
    return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2

def LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h):
    return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h)

#
# Create a transparent canvas with Chroma keying and indexed color format (palette).
#

# Create a button to better see the transparency
btn=lv.btn(lv.scr_act())

# Create a buffer for the canvas
cbuf= bytearray(LV_CANVAS_BUF_SIZE_INDEXED_1BIT(CANVAS_WIDTH, CANVAS_HEIGHT))

# Create a canvas and initialize its palette
canvas = lv.canvas(lv.scr_act())
canvas.set_buffer(cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, lv.img.CF.INDEXED_1BIT)
canvas.set_palette(0, LV_COLOR_CHROMA_KEY)
canvas.set_palette(1, lv.palette_main(lv.PALETTE.RED))

# Create colors with the indices of the palette
c0 = lv.color_t()
c1 = lv.color_t()

c0.full = 0
c1.full = 1

# Red background (There is no dedicated alpha channel in indexed images so LV_OPA_COVER is ignored)
canvas.fill_bg(c1, lv.OPA.COVER)

# Create hole on the canvas
for y in range(10,30):
    for x in range(5,20):
        canvas.set_px(x, y, c0)

API

Functions

lv_obj_t *lv_canvas_create(lv_obj_t *parent)

Create a canvas object

Parameters

parent -- pointer to an object, it will be the parent of the new canvas

Returns

pointer to the created canvas

void lv_canvas_set_buffer(lv_obj_t *canvas, void *buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)

Set a buffer for the canvas.

Parameters
  • buf -- a buffer where the content of the canvas will be. The required size is (lv_img_color_format_get_px_size(cf) * w) / 8 * h) It can be allocated with lv_mem_alloc() or it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or it can be an address in RAM or external SRAM

  • canvas -- pointer to a canvas object

  • w -- width of the canvas

  • h -- height of the canvas

  • cf -- color format. LV_IMG_CF_...

void lv_canvas_set_px_color(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)

Set the color of a pixel on the canvas

Parameters
  • canvas --

  • x -- x coordinate of the point to set

  • y -- x coordinate of the point to set

  • c -- color of the pixel

static inline void lv_canvas_set_px(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)

DEPRECATED: added only for backward compatibility

void lv_canvas_set_px_opa(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, lv_opa_t opa)

Set the opacity of a pixel on the canvas

Parameters
  • canvas --

  • x -- x coordinate of the point to set

  • y -- x coordinate of the point to set

  • opa -- opacity of the pixel (0..255)

void lv_canvas_set_palette(lv_obj_t *canvas, uint8_t id, lv_color_t c)

Set the palette color of a canvas with index format. Valid only for LV_IMG_CF_INDEXED1/2/4/8

Parameters
  • canvas -- pointer to canvas object

  • id -- the palette color to set:

    • for LV_IMG_CF_INDEXED1: 0..1

    • for LV_IMG_CF_INDEXED2: 0..3

    • for LV_IMG_CF_INDEXED4: 0..15

    • for LV_IMG_CF_INDEXED8: 0..255

  • c -- the color to set

lv_color_t lv_canvas_get_px(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y)

Get the color of a pixel on the canvas

Parameters
  • canvas --

  • x -- x coordinate of the point to set

  • y -- x coordinate of the point to set

Returns

color of the point

lv_img_dsc_t *lv_canvas_get_img(lv_obj_t *canvas)

Get the image of the canvas as a pointer to an lv_img_dsc_t variable.

Parameters

canvas -- pointer to a canvas object

Returns

pointer to the image descriptor.

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)

Copy a buffer to the canvas

Parameters
  • canvas -- pointer to a canvas object

  • to_copy -- buffer to copy. The color format has to match with the canvas's buffer color format

  • x -- left side of the destination position

  • y -- top side of the destination position

  • w -- width of the buffer to copy

  • h -- height of the buffer to copy

void lv_canvas_transform(lv_obj_t *canvas, lv_img_dsc_t *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)

Transform and image and store the result on a canvas.

Parameters
  • canvas -- pointer to a canvas object to store the result of the transformation.

  • img -- pointer to an image descriptor to transform. Can be the image descriptor of an other canvas too (lv_canvas_get_img()).

  • angle -- the angle of rotation (0..3600), 0.1 deg resolution

  • zoom -- zoom factor (256 no zoom);

  • offset_x -- offset X to tell where to put the result data on destination canvas

  • offset_y -- offset X to tell where to put the result data on destination canvas

  • pivot_x -- pivot X of rotation. Relative to the source canvas Set to source width / 2 to rotate around the center

  • pivot_y -- pivot Y of rotation. Relative to the source canvas Set to source height / 2 to rotate around the center

  • antialias -- apply anti-aliasing during the transformation. Looks better but slower.

void lv_canvas_blur_hor(lv_obj_t *canvas, const lv_area_t *area, uint16_t r)

Apply horizontal blur on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • area -- the area to blur. If NULL the whole canvas will be blurred.

  • r -- radius of the blur

void lv_canvas_blur_ver(lv_obj_t *canvas, const lv_area_t *area, uint16_t r)

Apply vertical blur on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • area -- the area to blur. If NULL the whole canvas will be blurred.

  • r -- radius of the blur

void lv_canvas_fill_bg(lv_obj_t *canvas, lv_color_t color, lv_opa_t opa)

Fill the canvas with color

Parameters
  • canvas -- pointer to a canvas

  • color -- the background color

  • opa -- the desired opacity

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)

Draw a rectangle on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • x -- left coordinate of the rectangle

  • y -- top coordinate of the rectangle

  • w -- width of the rectangle

  • h -- height of the rectangle

  • draw_dsc -- descriptor of the rectangle

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)

Draw a text on the canvas.

Parameters
  • canvas -- pointer to a canvas object

  • x -- left coordinate of the text

  • y -- top coordinate of the text

  • max_w -- max width of the text. The text will be wrapped to fit into this size

  • draw_dsc -- pointer to a valid label descriptor lv_draw_label_dsc_t

  • txt -- text to display

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)

Draw an image on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • x -- left coordinate of the image

  • y -- top coordinate of the image

  • src -- image source. Can be a pointer an lv_img_dsc_t variable or a path an image.

  • draw_dsc -- pointer to a valid label descriptor lv_draw_img_dsc_t

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)

Draw a line on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • points -- point of the line

  • point_cnt -- number of points

  • draw_dsc -- pointer to an initialized lv_draw_line_dsc_t variable

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)

Draw a polygon on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • points -- point of the polygon

  • point_cnt -- number of points

  • draw_dsc -- pointer to an initialized lv_draw_rect_dsc_t variable

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)

Draw an arc on the canvas

Parameters
  • canvas -- pointer to a canvas object

  • x -- origo x of the arc

  • y -- origo y of the arc

  • r -- radius of the arc

  • start_angle -- start angle in degrees

  • end_angle -- end angle in degrees

  • draw_dsc -- pointer to an initialized lv_draw_line_dsc_t variable

Variables

const lv_obj_class_t lv_canvas_class
struct lv_canvas_t

Public Members

lv_img_t img
lv_img_dsc_t dsc