LVGL9 Snapshot 功能简介与使用指南


什么是 Snapshot?

Snapshot 是 LVGL 提供的一项功能,用于对一个对象及其所有子对象进行快照,生成一个静态图像描述符。这张快照图像会精确地反映对象在显示屏上的外观,包括背景颜色、样式及其所有子对象。通过快照功能,开发者可以将动态界面内容冻结为图像,用于备份、特效实现或其他用途。


Snapshot 的用途

  1. 保存界面状态
    通过生成快照,可以记录当前界面的显示状态,并在需要时还原或参考。

  2. 特效处理
    结合快照,可以实现动态过渡、模糊或旋转等特效,而无需实时重绘整个界面。

  3. 离屏渲染
    对象快照是离屏渲染的一种形式,可用于优化复杂界面的绘制性能。

  4. 动画和效果实现
    将快照作为静态图像,可以轻松为其添加缩放、旋转等效果,而无需复杂的对象处理逻辑。


使用 Snapshot 的基础知识

支持的颜色格式

目前,Snapshot 功能支持以下颜色格式:

  • LV_COLOR_FORMAT_RGB565
  • LV_COLOR_FORMAT_RGB888
  • LV_COLOR_FORMAT_XRGB8888
  • LV_COLOR_FORMAT_ARGB8888

Snapshot 的核心 API

1. 生成快照

调用以下 API 可以生成快照:

lv_image_dsc_t * lv_snapshot_take(lv_obj_t * obj, lv_color_format_t color_format);
  • obj 是需要快照的对象。
  • color_format 指定快照的颜色格式。
  • 返回值是一个 lv_image_dsc_t 指针,用于描述快照图像。

快照生成后,可以使用 lv_image_set_src() 将其设置为图像对象的源数据。


2. 释放快照

生成的快照需要动态分配内存,因此使用完成后需要释放内存。可以使用以下函数释放:

void lv_snapshot_free(lv_image_dsc_t * snapshot);

注意在释放快照之前,需要先将其与图像对象解除关联:

lv_image_set_src(img_obj, NULL);
lv_cache_invalidate(lv_cache_find(src, LV_CACHE_SRC_TYPE_PTR, 0, 0));

3. 使用已有缓冲区生成快照

如果需要反复更新快照或提供自定义内存,可以使用以下 API:

lv_result_t lv_snapshot_take_to_buf(
    lv_obj_t * obj,
    lv_color_format_t cf,
    lv_image_dsc_t * dsc,
    void * buf,
    uint32_t buf_size
);

此函数将快照数据存储到用户提供的缓冲区 buf 中。如果成功,图像描述符 dsc 会被更新,指向生成的快照数据。

在调用之前,可以使用以下函数计算所需缓冲区大小:

uint32_t lv_snapshot_buf_size_needed(lv_obj_t * obj, lv_color_format_t cf);

示例代码

以下是一个简单的 Snapshot 示例,展示如何为对象及其子对象生成快照并更新图像显示:

代码实现

#include "../../lv_examples.h"
#if LV_USE_SNAPSHOT && LV_BUILD_EXAMPLES

static void event_cb(lv_event_t * e)
{
    lv_obj_t * snapshot_obj = lv_event_get_user_data(e);
    lv_obj_t * img = lv_event_get_target(e);

    if (snapshot_obj) {
        lv_image_dsc_t * snapshot = (void *)lv_image_get_src(snapshot_obj);
        if (snapshot) {
            lv_snapshot_free(snapshot);
        }

        // 更新快照
        snapshot = lv_snapshot_take(img->parent, LV_COLOR_FORMAT_ARGB8888);
        if (snapshot == NULL)
            return;

        lv_image_set_src(snapshot_obj, snapshot);
    }
}

void lv_example_snapshot_1(void)
{
    LV_IMAGE_DECLARE(img_star);
    lv_obj_t * root = lv_screen_active();
    lv_obj_set_style_bg_color(root, lv_palette_main(LV_PALETTE_LIGHT_BLUE), 0);

    // 创建一个用于显示快照的图像对象
    lv_obj_t * snapshot_obj = lv_image_create(root);
    lv_obj_set_style_bg_color(snapshot_obj, lv_palette_main(LV_PALETTE_PURPLE), 0);
    lv_obj_set_style_bg_opa(snapshot_obj, LV_OPA_100, 0);
    lv_image_set_scale(snapshot_obj, 128);
    lv_image_set_rotation(snapshot_obj, 300);

    // 创建一个容器及其子对象
    lv_obj_t * container = lv_obj_create(root);
    lv_obj_center(container);
    lv_obj_set_size(container, 180, 180);
    lv_obj_set_flex_flow(container, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_flex_align(container, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_radius(container, 50, 0);

    lv_obj_t * img;
    int i;
    for (i = 0; i < 4; i++) {
        img = lv_image_create(container);
        lv_image_set_src(img, &img_star);
        lv_obj_set_style_bg_color(img, lv_color_black(), 0);
        lv_obj_set_style_bg_opa(img, LV_OPA_COVER, 0);
        lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);
        lv_obj_add_event_cb(img, event_cb, LV_EVENT_PRESSED, snapshot_obj);
        lv_obj_add_event_cb(img, event_cb, LV_EVENT_RELEASED, snapshot_obj);
    }
}

#endif

示例说明

  • 快照显示对象
    使用 snapshot_obj 作为显示快照的对象,并为其设置背景颜色、缩放比例和旋转角度。

  • 事件回调
    通过点击容器中的子对象触发事件更新快照,并显示在 snapshot_obj 上。

  • 动态快照更新
    快照会实时更新,反映目标对象及其子对象的最新状态。


注意事项

  1. 内存管理
    快照会动态分配内存,需要在使用完成后手动释放以避免内存泄漏。

  2. 缓冲区大小
    如果使用自定义缓冲区,需要提前检查所需大小,并动态调整以适配对象大小的变化。

  3. 图像对象关联
    在释放快照之前,确保已经解除与图像对象的关联,避免潜在的访问冲突。


总结

Snapshot 是 LVGL 中一个强大的工具,适用于动态界面捕获、特效实现和优化渲染。通过简单的 API,开发者可以轻松生成对象快照并在界面中灵活应用。无论是实现复杂动画,还是记录界面状态,Snapshot 都是一个理想的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人才程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值