画布(Canvas)

画布控件提供基于 NanoVG 的 2D 图形绘制能力,并支持软件加速渲染和多种图像输出格式。



Warning

使用前需确保:帧缓冲区有足够内存。

组件概述

GUI Canvas 是基于 NanoVG 的 2D 绘图组件,提供:

  • 基础形状绘制(矩形/圆形/弧形等)

  • 支持 RGBA/RGB565/ PNG/JPG输出格式

  • NanoVG 软件加速渲染(通过 AGGE 后端)

  • 直接缓冲区输出功能

  • 空白缓冲区初始化支持

核心功能

创建与初始化

  1. 使用 gui_canvas_create 函数创建画布控件。

    此函数用于创建一个基于 NanoVG 的画布控件,返回画布对象指针。

    // 示例:创建200x200大小的画布
    gui_canvas_t* canvas = gui_canvas_create(
        parent,     // 父控件指针
        "my_canvas", // 画布名称
        NULL,       // 地址参数(保留)
        0, 0,       // x,y坐标
        200, 200    // 宽度,高度
    );
    
    if (canvas == NULL) {
        // 错误处理
    }
    
  2. 使用 gui_canvas_set_canvas_cb 设置绘制回调。

    此函数用于设置画布的重绘回调函数,当需要刷新画布时会调用此回调。

    // 示例绘制函数
    static void my_draw_function(gui_canvas_t* canvas) {
        NVGcontext* vg = canvas->vg;
    
        // 绘制红色矩形
        nvgBeginPath(vg);
        nvgRect(vg, 50, 50, 100, 100);
        nvgFillColor(vg, nvgRGBA(255, 0, 0, 255));
        nvgFill(vg);
    }
    
    // 设置回调
    gui_canvas_set_canvas_cb(canvas, my_draw_function);
    

触发重绘: 可通过设置 canvas->render = 1 来手动触发重绘,系统会在下一帧调用绘制回调。

图像输出

使用 gui_canvas_output_buffer 函数(预分配缓冲区)。

此函数需要预先分配缓冲区,适用于需要重复渲染或内存受限的场景。

// 示例:输出到预分配的RGBA缓冲区
uint8_t img_head_size = sizeof(gui_rgb_data_head_t);
uint32_t img_size = img_head_size + 640 * 480 * 4;// RGBA 需分配 width*height*4 字节,加上头部
uint8_t *buffer = gui_lower_malloc(img_size);
gui_canvas_render_to_image_buffer(
    GUI_CANVAS_OUTPUT_RGBA,
    false,
    640, 480,
    my_render_func,
    buffer);

示例代码

完整卡片视图使用示例:

menu_config.h 中开启宏定义 CONFIG_REALTEK_BUILD_CANVAS 来运行此示例。

#include <math.h>
#include "guidef.h"
#include "gui_img.h"
#include "gui_obj.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "gui_server.h"
#include "gui_components_init.h"
#include "gui_canvas.h"
#include "gui_canvas_rect.h"
#include "gui_canvas_round_rect.h"
#include "gui_canvas.h"

static void draw_circle_callback(gui_canvas_t *canvas)
{
    nvgBeginPath(canvas->vg);
    nvgCircle(canvas->vg, 100, 100, 50);
    nvgFillColor(canvas->vg, nvgRGBA(255, 255, 0, 255));
    nvgFill(canvas->vg);

    nvgBeginPath(canvas->vg);
    nvgEllipse(canvas->vg, 200, 100, 80, 40);
    nvgStrokeColor(canvas->vg, nvgRGBA(0, 0, 255, 255));
    nvgStrokeWidth(canvas->vg, 2.0f);
    nvgStroke(canvas->vg);
}

void test_circle_drawing(void)
{
    gui_canvas_t *canvas = gui_canvas_create(gui_obj_get_root(), "test_circle", NULL, 0, 0, 300, 200);
    gui_canvas_set_canvas_cb(canvas, draw_circle_callback);
}
static void canvas_rect_cb(gui_canvas_t *canvas)
{
    NVGcontext *vg = canvas->vg;
    nvgBeginPath(vg);
    nvgRoundedRect(vg, 150, 150, 200, 180, 20);

    nvgStrokeWidth(vg, 8.0f);
    nvgStrokeColor(vg, nvgRGB(255, 0, 0));
    nvgStroke(vg);

    NVGpaint gradient = nvgLinearGradient(vg, 150, 150, 350, 330, nvgRGB(255, 0, 0), nvgRGBA(0, 255, 0,
                                          255));
    nvgFillPaint(vg, gradient);
    nvgFill(vg);
}
void test_rect_drawing(void)
{

    gui_canvas_t *canvas = gui_canvas_create(gui_obj_get_root(), "canvas", 0, 0, 0, 480, 480);

    gui_canvas_set_canvas_cb(canvas, canvas_rect_cb);
}
static void arc_cb(gui_canvas_t *canvas)
{
    static float  progress;
    progress += 0.01f;
    nvgArc(canvas->vg, 480 / 2, 480 / 2, 150, 0, 3.14f * (sinf(progress) + 1), NVG_CCW);
    nvgStrokeWidth(canvas->vg, 20);
    nvgStrokeColor(canvas->vg, nvgRGB(178, 34, 34));
    nvgStroke(canvas->vg);
}

void test_arc_drawing(void)
{
    gui_canvas_t *canvas = gui_canvas_create(gui_obj_get_root(), "test_arc", NULL, 0, 0, 480, 480);
    gui_canvas_set_canvas_cb(canvas, arc_cb);
    canvas->render = 1;
}


static int app_init(void)
{
    test_rect_drawing();
    test_arc_drawing();
    test_circle_drawing();
    return 0;
}

GUI_INIT_APP_EXPORT(app_init);

API

Defines

GUI_CANVAS_OUTPUT_PNG 1
GUI_CANVAS_OUTPUT_JPG 2
GUI_CANVAS_OUTPUT_RGBA 3
GUI_CANVAS_OUTPUT_RGB565 4
GUI_CANVAS_OUTPUT_RGBA_NOMIX 5

Typedefs

typedef void (*gui_canvas_render_function)(NVGcontext *vg)

Functions

gui_canvas_t *gui_canvas_create(void *parent, const char *name, void *addr, int16_t x, int16_t y, int16_t w, int16_t h)

Create a canvas widget used to draw graphics in nanovg.

Parameters
  • parent -- Father widget nested in.

  • name -- Canvas widget's name.

  • addr -- Address of the canvas.

  • x -- X-axis coordinate relative to parent widget.

  • y -- Y-axis coordinate relative to parent widget.

  • w -- Width of the canvas.

  • h -- Height of the canvas.

Returns

Pointer to the created canvas widget.

void gui_canvas_set_canvas_cb(gui_canvas_t *this_widget, void (*cb)(gui_canvas_t *this_widget))

Set the callback function for drawing specific shapes.

Parameters
  • this_widget -- Pointer to the canvas widget.

  • cb -- Callback function for drawing specific shapes.

void *gui_canvas_render_to_image_buffer(int format, bool compression, int image_width, int image_height, gui_canvas_render_function renderer, uint8_t *target_buffer)

Render a graphical canvas to a specified buffer in a chosen image format.

Utilizes the provided renderer function to generate graphical content within a canvas, subsequently outputting the rendered image into the designated target buffer in accordance with the specified format. Optional compression is available based on the format.

Parameters
  • format -- Format of the output image. It should be specified as one of the following options:

    • GUI_CANVAS_OUTPUT_PNG for PNG format.

    • GUI_CANVAS_OUTPUT_JPG for JPG format.

    • GUI_CANVAS_OUTPUT_RGBA for RGBA format.

    • GUI_CANVAS_OUTPUT_RGB565 for RGB565 format.

  • compression -- Boolean flag indicating whether to compress the output image data. Note: Compression is only applicable for RGBA/RGB565 formats.

  • image_width -- Width of the output image, specified in pixels.

  • image_height -- Height of the output image, specified in pixels.

  • renderer -- Function pointer to the rendering callback function, responsible for executing drawing operations within the rendering context (NVGcontext).

  • target_buffer -- Pointer to the pre-allocated buffer designated for storing the rendered image data. Ensure the buffer size is adequate to hold the image data in the specified format.

Returns

Pointer to the rendered image buffer.

struct gui_canvas_t

Canvas structure.

Public Members

gui_obj_t base
NVGcontext *vg
void (*nanovg_canvas_cb)(struct gui_canvas *this_widget)
uint8_t checksum
uint8_t render