文章目录
什么是 Snapshot?
Snapshot 是 LVGL 提供的一项功能,用于对一个对象及其所有子对象进行快照,生成一个静态图像描述符。这张快照图像会精确地反映对象在显示屏上的外观,包括背景颜色、样式及其所有子对象。通过快照功能,开发者可以将动态界面内容冻结为图像,用于备份、特效实现或其他用途。
Snapshot 的用途
-
保存界面状态
通过生成快照,可以记录当前界面的显示状态,并在需要时还原或参考。 -
特效处理
结合快照,可以实现动态过渡、模糊或旋转等特效,而无需实时重绘整个界面。 -
离屏渲染
对象快照是离屏渲染的一种形式,可用于优化复杂界面的绘制性能。 -
动画和效果实现
将快照作为静态图像,可以轻松为其添加缩放、旋转等效果,而无需复杂的对象处理逻辑。
使用 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
上。 -
动态快照更新
快照会实时更新,反映目标对象及其子对象的最新状态。
注意事项
-
内存管理
快照会动态分配内存,需要在使用完成后手动释放以避免内存泄漏。 -
缓冲区大小
如果使用自定义缓冲区,需要提前检查所需大小,并动态调整以适配对象大小的变化。 -
图像对象关联
在释放快照之前,确保已经解除与图像对象的关联,避免潜在的访问冲突。
总结
Snapshot 是 LVGL 中一个强大的工具,适用于动态界面捕获、特效实现和优化渲染。通过简单的 API,开发者可以轻松生成对象快照并在界面中灵活应用。无论是实现复杂动画,还是记录界面状态,Snapshot 都是一个理想的解决方案。