[English]

Snapshot(快照)

显示原文

Snapshot provides API to take snapshot image for LVGL object together with its children. The image will look exactly like the object on display.


快照提供API来为LVGL对象及其子对象生成快照图像。图像看起来与显示看到的完全一样。

Usage(用法)

显示原文

Simply call API lv_snapshot_take() to generate the image descriptor which can be set as image object src using lv_image_set_src().

Note, only following color formats are supported for now:


只需调用API lv_snapshot_take() 来生成图像描述符,可以通过函数 lv_image_set_src() 将其设置为图像对象的图像源。

注意,目前仅支持以下颜色格式:

Free the Image(释放图像)

显示原文

The memory lv_snapshot_take() uses are dynamically allocated using lv_draw_buf_create(). Use API lv_draw_buf_destroy() to free the memory it takes. This will firstly free memory the image data takes, then the image descriptor.

The snapshot image which is the draw buffer returned by lv_snapshot_take() normally won't be added to cache because it can be drawn directly. So you don't need to invalidate cache by lv_image_cache_drop() before destroy the draw buffer.

Below code snippet explains usage of this API.

void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot)
{
    lv_draw_buf_t* snapshot = (void*)lv_image_get_src(img_snapshot);
    if(snapshot) {
        lv_draw_buf_destroy(snapshot);
    }
    snapshot = lv_snapshot_take(obj, LV_COLOR_FORMAT_ARGB8888);
    lv_image_set_src(img_snapshot, snapshot);
}

函数 lv_snapshot_take() 消耗的内存是通过 lv_draw_buf_create() 动态分配的。 需要使用函数 lv_draw_buf_destroy() 来释放它所占用的内存,这会首先释放图像数据所占用的内存,然后释放图像描述符。

通过 lv_snapshot_take() 返回的绘图缓冲区通常不会被添加到缓存中,因为它可以直接绘制。因此,在删除绘图缓冲区之前,您不需要通过 lv_image_cache_drop() 来使缓存失效。

下面的代码片段解释了 lv_snapshot_take() 的用法:

void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot)
{
    lv_draw_buf_t* snapshot = (void*)lv_image_get_src(img_snapshot);
    if(snapshot) {
        lv_draw_buf_destroy(snapshot);
    }
    snapshot = lv_snapshot_take(obj, LV_COLOR_FORMAT_ARGB8888);
    lv_image_set_src(img_snapshot, snapshot);
}

Use Existing Buffer(使用现有的缓冲区)

显示原文

If the snapshot needs update now and then, or simply caller provides memory, use API lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, lv_draw_buf_t * draw_buf); for this case. It's caller's responsibility to create and destroy the draw buffer.

If snapshot is generated successfully, the image descriptor is updated and image data will be stored to provided buf.

Note that snapshot may fail if provided buffer is not enough, which may happen when object size changes. It's recommended to use API lv_snapshot_reshape_draw_buf() to prepare the buffer firstly and if it fails, destroy the existing draw buffer and call lv_snapshot_take directly.


如果快照需要不时更新,或者只是调用方提供内存,可以使用API lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, lv_draw_buf_t * draw_buf); 来处理这种情况。创建和销毁绘制缓冲区是调用者的责任(LVGL不处理)。

如果快照生成成功,则更新图像描述符,并将图像数据存储到提供的“buf”中。

需要注意的是,如果提供的缓冲区不够大,快照可能会失败,这可能发生在对象大小发生变化时。建议使用API lv_snapshot_reshape_draw_buf() 来预先准备缓冲区,如果失败,销毁现有的绘制缓冲区并直接调用 lv_snapshot_take

Example

[English]

Simple snapshot example

#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_draw_buf_t * snapshot = (lv_draw_buf_t *)lv_image_get_src(snapshot_obj);
        if(snapshot) {
            lv_draw_buf_destroy(snapshot);
        }

        /*Update the snapshot, we know parent of object is the container.*/
        snapshot = lv_snapshot_take(lv_obj_get_parent(img), 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);

    /*Create an image object to show snapshot*/
    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);

    /*Create the container and its children*/
    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_set_style_transform_scale(img, 400, LV_STATE_PRESSED);
        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

API

lv_snapshot.h