news 2026/5/11 12:43:46

LVGL Canvas画布实战:5分钟教你制作一个可交互的简易绘图板

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LVGL Canvas画布实战:5分钟教你制作一个可交互的简易绘图板

LVGL Canvas画布实战:5分钟教你制作一个可交互的简易绘图板

在嵌入式GUI开发领域,LVGL因其轻量级和高度可定制性成为众多开发者的首选。而Canvas画布控件作为其核心组件之一,能够实现从简单图形绘制到复杂交互界面的各种功能。今天,我们就来探索如何利用LVGL Canvas快速搭建一个简易的触摸绘图板,让你在5分钟内实现手指或触控笔的实时绘图体验。

这个项目特别适合对GUI交互开发感兴趣的初学者和创客。通过这个实践,你不仅能掌握Canvas的基本用法,还能深入理解LVGL的事件处理机制。我们将从零开始,一步步构建这个交互式应用,涵盖从缓冲区设置、坐标映射到触摸事件处理的完整流程。

1. 环境准备与基础配置

在开始之前,确保你已经搭建好LVGL的开发环境。这里我们假设你使用的是PlatformIO+Arduino的开发方式,但原理同样适用于其他平台。

首先,我们需要创建一个足够大的缓冲区来存储Canvas的内容。这个缓冲区的大小直接决定了画布的分辨率和内存占用:

#define CANVAS_WIDTH 320 #define CANVAS_HEIGHT 240 static lv_color_t canvas_buffer[CANVAS_WIDTH * CANVAS_HEIGHT];

接下来,初始化Canvas对象并设置其基本属性:

lv_obj_t * canvas = lv_canvas_create(lv_scr_act(), NULL); lv_canvas_set_buffer(canvas, canvas_buffer, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR); lv_obj_set_pos(canvas, 0, 0); lv_obj_set_size(canvas, CANVAS_WIDTH, CANVAS_HEIGHT);

提示:缓冲区大小应根据你的硬件性能合理设置。对于内存受限的设备,可以考虑降低分辨率或使用索引颜色模式。

2. 实现基本绘图功能

Canvas提供了丰富的绘图API,我们先实现最基本的画线功能。首先定义一个结构体来保存绘图状态:

typedef struct { lv_point_t last_point; bool is_drawing; lv_color_t pen_color; uint8_t pen_width; } drawing_state_t; static drawing_state_t draw_state = { .pen_color = LV_COLOR_RED, .pen_width = 3 };

然后实现画线函数,它将在两点之间绘制一条线段:

void draw_line(lv_obj_t * canvas, lv_point_t * points, uint16_t point_cnt) { lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); line_dsc.color = draw_state.pen_color; line_dsc.width = draw_state.pen_width; line_dsc.round_end = 1; lv_canvas_draw_line(canvas, points, point_cnt, &line_dsc); }

3. 处理触摸事件

LVGL的事件系统是我们实现交互功能的关键。我们需要为Canvas添加触摸事件处理函数:

static void event_handler(lv_obj_t * obj, lv_event_t event) { if(event == LV_EVENT_PRESSED) { draw_state.is_drawing = true; lv_indev_get_point(lv_indev_get_act(), &draw_state.last_point); } else if(event == LV_EVENT_PRESSING) { lv_point_t current_point; lv_indev_get_point(lv_indev_get_act(), &current_point); lv_point_t points[2] = {draw_state.last_point, current_point}; draw_line(obj, points, 2); draw_state.last_point = current_point; } else if(event == LV_EVENT_RELEASED) { draw_state.is_drawing = false; } } lv_obj_set_event_cb(canvas, event_handler);

这段代码实现了:

  • 按下时开始绘制
  • 移动时连续画线
  • 释放时结束绘制

4. 增强功能与优化

基本的绘图功能已经实现,现在我们来添加一些增强功能提升用户体验。

4.1 颜色选择器

添加一个简单的颜色选择面板:

lv_obj_t * btn_red = lv_btn_create(lv_scr_act(), NULL); lv_obj_set_pos(btn_red, 10, CANVAS_HEIGHT + 10); lv_obj_set_size(btn_red, 40, 40); lv_obj_set_style_local_bg_color(btn_red, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); static void color_btn_event(lv_obj_t * obj, lv_event_t event) { if(event == LV_EVENT_CLICKED) { draw_state.pen_color = lv_obj_get_style_bg_color(obj, LV_BTN_PART_MAIN); } } lv_obj_set_event_cb(btn_red, color_btn_event);

4.2 清空画布功能

添加一个清空按钮:

lv_obj_t * btn_clear = lv_btn_create(lv_scr_act(), NULL); lv_obj_set_pos(btn_clear, 60, CANVAS_HEIGHT + 10); lv_obj_set_size(btn_clear, 80, 40); lv_obj_t * label = lv_label_create(btn_clear, NULL); lv_label_set_text(label, "Clear"); lv_obj_set_event_cb(btn_clear, [](lv_obj_t * obj, lv_event_t event) { if(event == LV_EVENT_CLICKED) { lv_canvas_fill_bg(canvas, LV_COLOR_WHITE, LV_OPA_COVER); } });

4.3 笔触大小调整

添加滑块控制笔触大小:

lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL); lv_obj_set_pos(slider, 150, CANVAS_HEIGHT + 10); lv_obj_set_size(slider, 150, 20); lv_slider_set_range(slider, 1, 20); lv_slider_set_value(slider, draw_state.pen_width, LV_ANIM_OFF); lv_obj_set_event_cb(slider, [](lv_obj_t * obj, lv_event_t event) { if(event == LV_EVENT_VALUE_CHANGED) { draw_state.pen_width = lv_slider_get_value(obj); } });

5. 性能优化技巧

当绘图区域较大时,频繁刷新可能导致性能问题。以下是几个优化建议:

  1. 局部刷新:只刷新发生变化的部分区域

    lv_obj_invalidate_area(canvas, &invalid_area);
  2. 双缓冲技术:使用两个缓冲区交替绘制

    static lv_color_t canvas_buffer2[CANVAS_WIDTH * CANVAS_HEIGHT];
  3. 降低采样率:对于连续绘制,可以适当降低采样点数量

  4. 使用DMA加速:如果硬件支持,利用DMA传输图像数据

在实际项目中,我发现最影响性能的往往是内存访问速度。对于STM32等MCU,将Canvas缓冲区放在DTCM或SRAM中可以显著提升绘制速度。另外,合理设置LVGL的刷新周期也能平衡性能与流畅度。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 12:43:29

三步掌握B站字幕提取:从观看者到内容创作者的转变

三步掌握B站字幕提取:从观看者到内容创作者的转变 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 想要将B站视频中的知识精华转化为可编辑的文字资料吗…

作者头像 李华
网站建设 2026/5/11 12:41:40

5分钟快速上手:B站m4s缓存视频转换MP4的终极解决方案

5分钟快速上手:B站m4s缓存视频转换MP4的终极解决方案 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾因B站视频突然下架而懊…

作者头像 李华
网站建设 2026/5/11 12:40:40

System Cursor:打造系统级AI文本补全工具,实现无缝人机交互

1. 项目概述:一个无处不在的AI文本补全工具 如果你和我一样,每天要在不同的应用之间来回切换——写代码用VS Code,写文档用Obsidian,回邮件用Thunderbird,还得时不时切到浏览器查资料——那你肯定也烦透了那种“复制文…

作者头像 李华
网站建设 2026/5/11 12:38:29

cdma2000网络QoS优化与流量管理实践

1. cdma2000网络中的服务质量与流量管理概述在移动通信领域,服务质量(QoS)和流量管理是确保用户体验的核心技术要素。cdma2000作为第三代移动通信标准,通过一系列创新机制实现了对不同业务类型的差异化支持。这套系统最显著的特点是其能够根据应用特性动…

作者头像 李华