LVGL canvas的详细分析

LVGL的canvas小部件是一个简单而强大的组件,它允许在一个小部件上绘制像素级的内容。这通常用于自定义图形和文本,或者作为更复杂图形元素的基础。Canvas小部件提供了一个缓冲区,可以在其中绘制任何您想要的内容。

函数解说

1. lv_canvas_create


   创建一个新的 `canvas` 小部件实例。它调用 `lv_obj_class_create_obj` 来创建对象,并初始化它。lv_canvas_create 函数是 LVGL 图形库中用于创建一个新的 canvas 小部件的函数。canvas 小部件是一个类似于画布的界面元素,开发者可以在其上进行绘制操作,如自定义图形、文本和图像等。

lv_obj_t * lv_canvas_create(lv_obj_t * parent)
{
    LV_LOG_INFO("begin");  // 记录日志信息

    // 创建一个新的 canvas 小部件作为 parent 的子对象
    lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
    if(obj == NULL) {
        return NULL;  // 如果创建失败,则返回 NULL
    }

    // 初始化新创建的 canvas 小部件
    lv_obj_class_init_obj(obj);  // 调用对象类的初始化函数

    return obj;  // 返回新创建的 canvas 小部件对象
}

  1. 函数参数:

    • lv_obj_t * parent: 指向父对象的指针,新的 canvas 小部件将作为这个父对象的子对象创建。如果 parent 为 NULL,则新创建的 canvas 将成为顶层对象。
  2. 函数逻辑:

    • 首先,函数记录一个日志信息 "begin",表示开始创建 canvas 小部件。
    • 接下来,函数调用 lv_obj_class_create_obj 来创建一个新的 canvas 小部件对象。这个函数是 LVGL 对象系统的一部分,它会根据提供的类和父对象来创建一个新的对象。
    • 如果创建成功,函数调用 lv_obj_class_init_obj 来初始化新创建的 canvas 小部件。这个函数是 canvas 类的构造函数,它会设置小部件的默认属性和状态。
    • 最后,函数返回新创建的 canvas 小部件对象的指针。
  3. 使用场景:

    • lv_canvas_create 函数通常在需要在 LVGL 应用程序中添加一个新的 canvas 小部件时使用。
    • 开发者可以在创建 canvas 后,对其进行配置和绘制,以实现自定义的图形用户界面元素。
  4. 注意事项:

    • 在调用 lv_canvas_create 之前,需要确保 parent 对象是有效的,且已经创建和初始化。
    • 如果 parent 为 NULL,则新创建的 canvas 将成为顶层对象,这意味着它将直接附加到屏幕(lv_scr_act)上。
    • 创建 canvas 小部件后,可能需要对其进行进一步的配置,如设置大小、位置、背景颜色等,以及关联的绘制缓冲区。
    • 如果 lv_obj_class_create_obj 返回 NULL,则表示创建失败,此时应该检查原因并进行相应的错误处理。

通过 lv_canvas_create 函数,开发者可以在 LVGL 应用程序中创建一个新的 canvas 小部件,为自定义绘制和图像处理提供了基础。这是实现复杂用户界面和动态图形效果的重要步骤。

2. lv_canvas_set_buffer


   设置 `canvas` 小部件的绘制缓冲区。lv_canvas_set_buffer 函数是 LVGL 图形库中用于为 canvas 小部件设置一个新的绘制缓冲区的函数。这个函数允许开发者提供一个自定义的缓冲区,用于存储 canvas 小部件的像素数据,从而实现更灵活的图像处理和绘制操作。

void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, int32_t w, int32_t h, lv_color_format_t cf)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);  // 断言 obj 是一个有效的 canvas 对象
    LV_ASSERT_NULL(buf);          // 断言 buf 不为 NULL

    lv_canvas_t * canvas = (lv_canvas_t *)obj;
    uint32_t stride = lv_draw_buf_width_to_stride(w, cf);  // 计算缓冲区的跨度(stride)

    // 初始化新的绘制缓冲区
    lv_draw_buf_init(&canvas->static_buf, w, h, cf, stride, buf, stride * h);
    canvas->draw_buf = &canvas->static_buf;  // 设置 canvas 的绘制缓冲区为新初始化的缓冲区

    // 丢弃旧的图像源
    const void * src = lv_image_get_src(obj);
    if(src) {
        lv_image_cache_drop(src);
    }

    // 设置新的图像源为新的绘制缓冲区
    lv_image_set_src(obj, canvas->draw_buf);
    lv_image_cache_drop(canvas->draw_buf);  // 将新的绘制缓冲区添加到图像缓存中

    // 标记对象为无效,以便重新绘制
    lv_obj_invalidate(obj);
}

  1. 函数参数:

    • lv_obj_t * obj: 指向 canvas 小部件的指针。
    • void * buf: 指向新绘制缓冲区的指针。
    • int32_t w: 缓冲区的宽度(以像素为单位)。
    • int32_t h: 缓冲区的高度(以像素为单位)。
    • lv_color_format_t cf: 缓冲区的颜色格式。
  2. 函数逻辑:

    • 首先,函数通过 LV_ASSERT_OBJ 宏检查输入参数 obj 是否为有效的 canvas 小部件。
    • 然后,函数通过 LV_ASSERT_NULL 宏检查输入参数 buf 是否不为 NULL。
    • 接下来,函数计算新绘制缓冲区的跨度(stride),这是每一行像素的字节长度。
    • 函数使用 lv_draw_buf_init 初始化新的绘制缓冲区,这个函数会设置缓冲区的宽度、高度、颜色格式、跨度和数据指针。
    • 然后,函数将 canvas 小部件的 draw_buf 成员设置为新初始化的缓冲区。
    • 接下来,函数丢弃 canvas 小部件的旧图像源,如果是通过 lv_image_cache_get 获取的,则通过 lv_image_cache_drop 释放资源。
    • 函数将新的图像源设置为 canvas 小部件的 draw_buf 并将其添加到图像缓存中。
    • 最后,函数通过调用 lv_obj_invalidate 标记 canvas 小部件为无效,这将触发重新绘制 canvas 以反映新的绘制缓冲区。
  3. 使用场景:

    • lv_canvas_set_buffer 函数通常在以下场景中使用:
      • 当需要为 canvas 小部件提供一个自定义的绘制缓冲区时,例如,可能需要更大的缓冲区或者一个具有特定颜色格式的缓冲区。
      • 在实现自定义的绘制操作或者复杂的图像处理时,可能需要使用特定的绘制缓冲区。
      • 在动态调整 canvas 小部件的资源使用时,例如,在内存限制或性能优化的情况下。
  4. 注意事项:

    • 在调用 lv_canvas_set_buffer 之前,必须确保提供了一个有效的绘制缓冲区,并且该缓冲区的内存已经分配好。
    • 绘制缓冲区必须已经被正确初始化,且其大小要与 canvas 小部件的尺寸匹配。
    • 函数会自动处理旧绘制缓冲区的释放和新绘制缓冲区的缓存添加。
    • 修改绘制缓冲区后,可能需要重新绘制 canvas 小部件以显示更改。

通过 lv_canvas_set_buffer 函数,开发者可以为 canvas 小部件指定一个新的绘制缓冲区,这对于实现高级的图像处理和自定义绘制操作非常有用。然而,直接操作绘制缓冲区也需要对 LVGL 的内部工作机制和内存管理有深入的理解。

3. lv_canvas_set_draw_buf


   通过 `lv_draw_buf_t` 结构体设置 `canvas` 小部件的绘制缓冲区。lv_canvas_set_draw_buf 函数是 LVGL 图形库中用于设置 canvas 小部件的绘制缓冲区的函数。这个函数允许开发者为 canvas 小部件指定一个新的绘制缓冲区,这个缓冲区将用于存储 canvas 的像素数据,从而实现自定义的绘制操作。

void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);  // 断言 obj 是一个有效的 canvas 对象
    LV_ASSERT_NULL(draw_buf);      // 断言 draw_buf 不为 NULL

    lv_canvas_t * canvas = (lv_canvas_t *)obj;

    // 释放当前的绘制缓冲区(如果有的话)
    if(canvas->draw_buf) {
        lv_image_cache_drop(&canvas->draw_buf);
    }

    // 设置新的绘制缓冲区
    canvas->draw_buf = draw_buf;

    // 清除旧的图像源
    const void * src = lv_image_get_src(obj);
    if(src) {
        lv_image_cache_drop(src);
    }

    // 设置新的图像源为新的绘制缓冲区
    lv_image_set_src(obj, draw_buf);
    lv_image_cache_drop(draw_buf);  // 将新的绘制缓冲区添加到图像缓存中

    // 标记对象为无效,以便重新绘制
    lv_obj_invalidate(obj);
}

  1. 函数参数:

    • lv_obj_t * obj: 指向 canvas 小部件的指针。
    • lv_draw_buf_t * draw_buf: 指向新的绘制缓冲区的指针。
  2. 函数逻辑:

    • 首先,函数通过 LV_ASSERT_OBJ 宏检查输入参数 obj 是否为有效的 canvas 小部件。
    • 然后,函数通过 LV_ASSERT_NULL 宏检查输入参数 draw_buf 是否不为 NULL。
    • 接下来,函数释放 canvas 小部件当前的绘制缓冲区(如果有的话),这是通过调用 lv_image_cache_drop 函数完成的。
    • 然后,函数将 canvas 小部件的 draw_buf 成员设置为新的绘制缓冲区。
    • 接下来,函数清除 canvas 小部件的旧图像源,并将新的绘制缓冲区设置为图像源。
    • 最后,函数通过调用 lv_obj_invalidate 标记 canvas 小部件为无效,这将触发重新绘制 canvas 以反映新的绘制缓冲区。
  3. 使用场景:

    • lv_canvas_set_draw_buf 函数通常在以下场景中使用:
      • 当需要为 canvas 小部件更换一个新的绘制缓冲区时,例如,可能需要更大的缓冲区或者一个具有不同颜色格式的缓冲区。
      • 在实现自定义的绘制操作或者复杂的图像处理时,可能需要使用特定的绘制缓冲区。
      • 在动态调整 canvas 小部件的资源使用时,例如,在内存限制或性能优化的情况下。
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值