Canvas (lv_canvas)¶
Overview¶
A Canvas inherits from Image where the user can draw anything. Rectangles, texts, images, lines, arcs can be drawn here using lvgl's drawing engine. Additionally "effects" can be applied, such as rotation, zoom and blur.
Parts and Styles¶
LV_PART_MAIN
Uses the typical rectangle style properties and image style properties.
Usage¶
Buffer¶
The Canvas needs a buffer in which stores the drawn image.
To assign a buffer to a Canvas, use lv_canvas_set_buffer(canvas, buffer, width, height, LV_IMG_CF_...)
.
Where buffer
is a static buffer (not just a local variable) to hold the image of the canvas.
For example,
static lv_color_t buffer[LV_CANVAS_BUF_SIZE_TRUE_COLOR(width, height)]
.
LV_CANVAS_BUF_SIZE_...
macros help to determine the size of the buffer with different color formats.
The canvas supports all the built-in color formats like LV_IMG_CF_TRUE_COLOR
or LV_IMG_CF_INDEXED_2BIT
.
See the full list in the Color formats section.
Indexed colors¶
For LV_IMG_CF_INDEXED_1/2/4/8
color formats a palette needs to be
initialized with lv_canvas_set_palette(canvas, 3, LV_COLOR_RED)
. It sets pixels with index=3 to red.
Drawing¶
To set a pixel's color on the canvas, use lv_canvas_set_px_color(canvas, x, y, LV_COLOR_RED)
.
With LV_IMG_CF_INDEXED_...
the index of the color needs to be passed as color.
E.g. lv_color_t c; c.full = 3;
To set a pixel's opacity with LV_IMG_CF_TRUE_COLOR_ALPHA
or LV_IMG_CF_ALPHA_...
format on the canvas, use lv_canvas_set_px_opa(canvas, x, y, opa)
.
lv_canvas_fill_bg(canvas, LV_COLOR_BLUE, LV_OPA_50)
fills the whole canvas to blue with 50% opacity. Note that if the current color format doesn't support colors (e.g. LV_IMG_CF_ALPHA_2BIT
) the color will be ignored.
Similarly, if opacity is not supported (e.g. LV_IMG_CF_TRUE_COLOR
) it will be ignored.
An array of pixels can be copied to the canvas with lv_canvas_copy_buf(canvas, buffer_to_copy, x, y, width, height)
.
The color format of the buffer and the canvas need to match.
To draw something to the canvas use
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
is a lv_draw_rect/label/img/line/arc_dsc_t
variable which should be first initialized with one of lv_draw_rect/label/img/line/arc_dsc_init()
and then modified with the desired colors and other values.
The draw function can draw to any color format. For example, it's possible to draw a text to an LV_IMG_VF_ALPHA_8BIT
canvas and use the result image as a draw mask later.
Transformations¶
lv_canvas_transform()
can be used to rotate and/or scale the image of an image and store the result on the canvas.
The function needs the following 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 another canvas too (lv_canvas_get_img()
).angle
the angle of rotation (0..3600), 0.1 deg resolutionzoom
zoom factor (256: no zoom, 512: double size, 128: half size);offset_x
offset X to tell where to put the result data on destination canvasoffset_y
offset X to tell where to put the result data on destination canvaspivot_x
pivot X of rotation. Relative to the source canvas. Set tosource width / 2
to rotate around the centerpivot_y
pivot Y of rotation. Relative to the source canvas. Set tosource height / 2
to rotate around the centerantialias
true: apply anti-aliasing during the transformation. Looks better but slower.
Note that a canvas can't be rotated on itself. You need a source and destination canvas or image.
Blur¶
A given area of the canvas can be blurred horizontally with lv_canvas_blur_hor(canvas, &area, r)
or vertically with lv_canvas_blur_ver(canvas, &area, r)
.
r
is the radius of the blur (greater value means more intensive burring). area
is the area where the blur should be applied (interpreted relative to the canvas).
Events¶
No special events are sent by canvas objects. The same events are sent as for the
See the events of the Images too.
Learn more about Events.
Example¶
Drawing on the Canvas and rotate¶
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
_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)
Transparent Canvas with chroma keying¶
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
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 SRAMcanvas -- 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..1for
LV_IMG_CF_INDEXED2
: 0..3for
LV_IMG_CF_INDEXED4
: 0..15for
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 centerpivot_y -- pivot Y of rotation. Relative to the source canvas Set to
source height / 2
to rotate around the centerantialias -- 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¶