Canvas (lv_canvas)¶
Overview¶
A Canvas is like an Image where the user can draw anything.
Buffer¶
The Canvas needs a buffer which stores the drawn image.
To assign a buffer to a Canvas, use lv_canvas_set_buffer(canvas, buffer, width, height, LV_IMG_CF_...)
.
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.
Palette¶
For LV_IMG_CF_INDEXED_...
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 on the canvas, use lv_canvas_set_px(canvas, x, y, LV_COLOR_RED)
.
With LV_IMG_CF_INDEXED_...
or LV_IMG_CF_ALPHA_...
, the index of the color or the alpha value needs to be passed as color. E.g. lv_color_t c; c.full = 3;
lv_canvas_fill_bg(canvas, LV_COLOR_BLUE)
fills the whole canvas to blue.
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, &style)
lv_canvas_draw_text(canvas, x, y, max_width, &style, txt, LV_LABEL_ALIGN_LEFT/CENTER/RIGTH)
lv_canvas_draw_img(canvas, x, y, &img_src, &style)
lv_canvas_draw_line(canvas, point_array, point_cnt, &style)
lv_canvas_draw_polygon(canvas, points_array, point_cnt, &style)
lv_canvas_draw_arc(canvas, x, y, radius, start_angle, end_angle, &style)
The draw function can draw only to LV_IMG_CF_TURE_COLOR
, LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED
and LV_IMG_CF_TRUE_COLOR_ALPHA
buffers. LV_IMG_CF_TRUE_COLOR_ALPHA
is working only with LV_COLOR_DEPTH 32
.
Rotate¶
A rotated image can be added to canvas with lv_canvas_rotate(canvas, &imd_dsc, angle, x, y, pivot_x, pivot_y)
.
It will rotate the image shown by img_dsc
around the given pivot and stores it on the x
, y
coordinates of canvas
.
Instead of img_dsc
, the buffer of another canvas also can be used by lv_canvas_get_img(canvas)
.
Note that a canvas can’t be rotated on itself. You need a source and destination canvas or image.
Styles¶
You can set the styles with lv_canvas_set_style(btn, LV_CANVAS_STYLE_MAIN, &style)
.
style.image.color
is used to tell the base color with LV_IMG_CF_ALPHA_...
color format.
Example¶
C¶
Drawing on the Canvas and rotate¶
code
#include "lvgl/lvgl.h"
#define CANVAS_WIDTH 200
#define CANVAS_HEIGHT 150
void lv_ex_canvas_1(void)
{
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_WHITE;
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;
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(), 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);
lv_canvas_draw_rect(canvas, 70, 60, 100, 70, &style);
lv_canvas_draw_text(canvas, 40, 20, 100, &style, "Some text on text canvas", LV_LABEL_ALIGN_LEFT);
/* Test the rotation. It requires an other buffer where the orignal image is stored.
* So copy the current image to buffer and rotate it to the canvas */
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_COLOR_SILVER);
lv_canvas_rotate(canvas, &img, 30, 0, 0, CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2);
}
Transparent Canvas with chroma keying¶
code
#include "lvgl/lvgl.h"
#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50
/**
* Create a transparent canvas with Chroma keying and indexed color format (palette).
*/
void lv_ex_canvas_2(void)
{
/*Create a button to better see the transparency*/
lv_btn_create(lv_scr_act(), NULL);
/*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 the palette*/
lv_obj_t * canvas = lv_canvas_create(lv_scr_act(), NULL);
lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_INDEXED_1BIT);
lv_canvas_set_palette(canvas, 0, LV_COLOR_TRANSP);
lv_canvas_set_palette(canvas, 1, LV_COLOR_RED);
/*Create colors with the indices of the palette*/
lv_color_t c0;
lv_color_t c1;
c0.full = 0;
c1.full = 1;
/*Transparent background*/
lv_canvas_fill_bg(canvas, c1);
/*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(canvas, x, y, c0);
}
}
}
MicroPython¶
Drawing on the Canvas and rotate¶
code
CANVAS_WIDTH = 200
CANVAS_HEIGHT = 150
style = lv.style_t()
lv.style_copy(style, lv.style_plain)
style.body.main_color = lv.color_make(0xFF,0,0)
style.body.grad_color = lv.color_make(0x80,0,0)
style.body.radius = 4
style.body.border.width = 2
style.body.border.color = lv.color_make(0xFF,0xFF,0xFF)
style.body.shadow.color = lv.color_make(0xFF,0xFF,0xFF)
style.body.shadow.width = 4
style.line.width = 2
style.line.color = lv.color_make(0,0,0)
style.text.color = lv.color_make(0,0,0xFF)
# CF.TRUE_COLOR requires 4 bytes per pixel
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.align(None, lv.ALIGN.CENTER, 0, 0)
canvas.fill_bg(lv.color_make(0xC0, 0xC0, 0xC0))
canvas.draw_rect(70, 60, 100, 70, style)
canvas.draw_text(40, 20, 100, style, "Some text on text canvas", lv.label.ALIGN.LEFT)
# Test the rotation. It requires an other buffer where the orignal 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.color_make(0xC0, 0xC0, 0xC0))
canvas.rotate(img, 30, 0, 0, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)
Transparent Canvas with chroma keying¶
code
# Create a transparent canvas with Chroma keying and indexed color format (palette).
CANVAS_WIDTH = 50
CANVAS_HEIGHT = 50
def bufsize(w, h, bits, indexed=False):
"""this function determines required buffer size
depending on the color depth"""
size = (w * bits // 8 + 1) * h
if indexed:
# + 4 bytes per palette color
size += 4 * (2**bits)
return size
# Create a button to better see the transparency
lv.btn(lv.scr_act())
# Create a buffer for the canvas
cbuf = bytearray(bufsize(CANVAS_WIDTH, CANVAS_HEIGHT, 1, indexed=True))
# Create a canvas and initialize its the palette
canvas = lv.canvas(lv.scr_act())
canvas.set_buffer(cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, lv.img.CF.INDEXED_1BIT)
# transparent color can be defined in lv_conf.h and set to pure green by default
canvas.set_palette(0, lv.color_make(0x00, 0xFF, 0x00))
canvas.set_palette(1, lv.color_make(0xFF, 0x00, 0x00))
# Create colors with the indices of the palette
c0 = lv.color_t()
c1 = lv.color_t()
c0.full = 0
c1.full = 1
# Transparent background
canvas.fill_bg(c1)
# Create hole on the canvas
for y in range(10,30):
for x in range(5, 20):
canvas.set_px(x, y, c0)
API¶
Typedefs
-
typedef uint8_t
lv_canvas_style_t
¶
Functions
-
lv_obj_t *
lv_canvas_create
(lv_obj_t *par, const lv_obj_t *copy)¶ Create a canvas object
- Return
pointer to the created canvas
- Parameters
par
: pointer to an object, it will be the parent of the new canvascopy
: pointer to a canvas object, if not NULL then the new object will be copied from it
-
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 * h) / 8) It can be allocated withlv_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 objectw
: width of the canvash
: height of the canvascf
: color format.LV_IMG_CF_...
-
void
lv_canvas_set_px
(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 sety
: x coordinate of the point to setc
: color of the point
-
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 objectid
: 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
-
void
lv_canvas_set_style
(lv_obj_t *canvas, lv_canvas_style_t type, const lv_style_t *style)¶ Set a style of a canvas.
- Parameters
canvas
: pointer to canvas objecttype
: which style should be setstyle
: pointer to a style
-
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
- Return
color of the point
- Parameters
canvas
:x
: x coordinate of the point to sety
: x coordinate of the point to set
-
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.- Return
pointer to the image descriptor.
- Parameters
canvas
: pointer to a canvas object
-
const lv_style_t *
lv_canvas_get_style
(const lv_obj_t *canvas, lv_canvas_style_t type)¶ Get style of a canvas.
- Return
style pointer to the style
- Parameters
canvas
: pointer to canvas objecttype
: which style should be get
-
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 objectto_copy
: buffer to copy. The color format has to match with the canvas’s buffer color formatx
: left side of the destination positiony
: top side of the destination positionw
: width of the buffer to copyh
: height of the buffer to copy
-
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)¶ Rotate and image and store the result on a canvas.
- Parameters
canvas
: pointer to a canvas objectimg
: pointer to an image descriptor. Can be the image descriptor of an other canvas too (lv_canvas_get_img()
).angle
: the angle of rotation (0..360);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 center
-
void
lv_canvas_fill_bg
(lv_obj_t *canvas, lv_color_t color)¶ Fill the canvas with color
- Parameters
canvas
: pointer to a canvascolor
: the background 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)¶ Draw a rectangle on the canvas
- Parameters
canvas
: pointer to a canvas objectx
: left coordinate of the rectangley
: top coordinate of the rectanglew
: width of the rectangleh
: height of the rectanglestyle
: style of the rectangle (body
properties are used exceptpadding
)
-
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)¶ Draw a text on the canvas.
- Parameters
canvas
: pointer to a canvas objectx
: left coordinate of the texty
: top coordinate of the textmax_w
: max width of the text. The text will be wrapped to fit into this sizestyle
: style of the text (text
properties are used)txt
: text to displayalign
: align of the text (LV_LABEL_ALIGN_LEFT/RIGHT/CENTER
)
-
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)¶ Draw an image on the canvas
- Parameters
canvas
: pointer to a canvas objectsrc
: image source. Can be a pointer anlv_img_dsc_t
variable or a path an image.style
: style of the image (image
properties are used)
-
void
lv_canvas_draw_line
(lv_obj_t *canvas, const lv_point_t *points, uint32_t point_cnt, const lv_style_t *style)¶ Draw a line on the canvas
- Parameters
canvas
: pointer to a canvas objectpoints
: point of the linepoint_cnt
: number of pointsstyle
: style of the line (line
properties are used)
-
void
lv_canvas_draw_polygon
(lv_obj_t *canvas, const lv_point_t *points, uint32_t point_cnt, const lv_style_t *style)¶ Draw a polygon on the canvas
- Parameters
canvas
: pointer to a canvas objectpoints
: point of the polygonpoint_cnt
: number of pointsstyle
: style of the polygon (body.main_color
andbody.opa
is used)
-
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)¶ Draw an arc on the canvas
- Parameters
canvas
: pointer to a canvas objectx
: origo x of the arcy
: origo y of the arcr
: radius of the arcstart_angle
: start angle in degreesend_angle
: end angle in degreesstyle
: style of the polygon (body.main_color
andbody.opa
is used)
-
struct
lv_canvas_ext_t
¶