快照

快照提供了用于为 LVGL 对象及其子对象生成快照图像的 API。生成的图像将与对象完全一致。

用法

只需调用 API lv_snapshot_take 即可生成图像描述符,然后可以使用 lv_img_set_src 将其设置为图像对象的源。

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

  • LV_IMG_CF_TRUE_COLOR_ALPHA

  • LV_IMG_CF_ALPHA_1BIT

  • LV_IMG_CF_ALPHA_2BIT

  • LV_IMG_CF_ALPHA_4BIT

  • LV_IMG_CF_ALPHA_8BIT

释放图像

lv_snapshot_take 使用的内存是通过 lv_mem_alloc 动态分配的。使用 API lv_snapshot_free 释放其占用的内存。此操作将首先释放图像数据占用的内存,然后释放图像描述符。

需要注意的是,释放快照时不要删除图像对象。在释放内存之前,请确保首先将其从图像对象中解除链接,使用 lv_img_set_src(NULL)lv_img_cache_invalidate_src(src)

以下代码片段说明了此 API 的用法:

void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot)
{
    lv_img_dsc_t* snapshot = (void*)lv_img_get_src(img_snapshot);
    if(snapshot) {
        lv_snapshot_free(snapshot);
    }
    snapshot = lv_snapshot_take(obj, LV_IMG_CF_TRUE_COLOR_ALPHA);
    lv_img_set_src(img_snapshot, snapshot);
}

使用现有缓冲区

如果需要频繁更新快照,或者调用者提供了内存,可以使用 API lv_res_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_img_cf_t cf, lv_img_dsc_t * dsc, void * buf, uint32_t buff_size);。在这种情况下,分配/释放内存的责任由调用者承担。

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

注意,如果提供的缓冲区不足,快照可能会失败,这在对象大小发生变化时可能会发生。建议首先使用 API lv_snapshot_buf_size_needed 检查所需的缓冲区大小(以字节为单位),并相应地调整缓冲区大小。

示例

简单的快照示例

C code  

 GitHub
#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_img_dsc_t * snapshot = (void *)lv_img_get_src(snapshot_obj);
        if(snapshot) {
            lv_snapshot_free(snapshot);
        }

        /*Update the snapshot, we know parent of object is the container.*/
        snapshot = lv_snapshot_take(img->parent, LV_IMG_CF_TRUE_COLOR_ALPHA);
        if(snapshot == NULL)
            return;
        lv_img_set_src(snapshot_obj, snapshot);
    }
}

void lv_example_snapshot_1(void)
{
    LV_IMG_DECLARE(img_star);
    lv_obj_t * root = lv_scr_act();
    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_img_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_img_set_zoom(snapshot_obj, 128);
    lv_img_set_angle(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_img_create(container);
        lv_img_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_zoom(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

MicroPython code  

 GitHub Simulator
import gc
import lvgl as lv
from imagetools import get_png_info, open_png

# Register PNG image decoder
decoder = lv.img.decoder_create()
decoder.info_cb = get_png_info
decoder.open_cb = open_png

# Measure memory usage
gc.enable()
gc.collect()
mem_free = gc.mem_free()

label = lv.label(lv.scr_act())
label.align(lv.ALIGN.BOTTOM_MID, 0, -10)
label.set_text(" memory free:" + str(mem_free/1024) + " kB")

# Create an image from the png file
try:
    with open('../../assets/img_star.png','rb') as f:
        png_data = f.read()
except:
    print("Could not find star.png")
    sys.exit()

img_star = lv.img_dsc_t({
  'data_size': len(png_data),
  'data': png_data
})

def event_cb(e, snapshot_obj):
    img = e.get_target()

    if snapshot_obj:
        # no need to free the old source for snapshot_obj, gc will free it for us.

        # take a new snapshot, overwrite the old one
        dsc = lv.snapshot_take(img.get_parent(), lv.img.CF.TRUE_COLOR_ALPHA)
        snapshot_obj.set_src(dsc)

    gc.collect()
    mem_used = mem_free - gc.mem_free()
    label.set_text("memory used:" + str(mem_used/1024) + " kB")

root = lv.scr_act()
root.set_style_bg_color(lv.palette_main(lv.PALETTE.LIGHT_BLUE), 0)

# Create an image object to show snapshot
snapshot_obj = lv.img(root)
snapshot_obj.set_style_bg_color(lv.palette_main(lv.PALETTE.PURPLE), 0)
snapshot_obj.set_style_bg_opa(lv.OPA.COVER, 0)
snapshot_obj.set_zoom(128)

# Create the container and its children
container = lv.obj(root)
container.align(lv.ALIGN.CENTER, 0, 0)
container.set_size(180, 180)
container.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
container.set_flex_align(lv.FLEX_ALIGN.SPACE_EVENLY, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.CENTER)
container.set_style_radius(50, 0)

for i in range(4):
    img = lv.img(container)
    img.set_src(img_star)
    img.set_style_bg_color(lv.palette_main(lv.PALETTE.GREY), 0)
    img.set_style_bg_opa(lv.OPA.COVER, 0)
    img.set_style_transform_zoom(400, lv.STATE.PRESSED)
    img.add_flag(img.FLAG.CLICKABLE)
    img.add_event_cb(lambda e: event_cb(e, snapshot_obj), lv.EVENT.PRESSED, None)
    img.add_event_cb(lambda e: event_cb(e, snapshot_obj), lv.EVENT.RELEASED, None)

API

Functions

lv_img_dsc_t *lv_snapshot_take(lv_obj_t *obj, lv_img_cf_t cf)

Take snapshot for object with its children.

Parameters
  • obj -- The object to generate snapshot.

  • cf -- color format for generated image.

Returns

a pointer to an image descriptor, or NULL if failed.

void lv_snapshot_free(lv_img_dsc_t *dsc)

Free the snapshot image returned by lv_snapshot_take

It will firstly free the data image takes, then the image descriptor.

Parameters

dsc -- The image descriptor generated by lv_snapshot_take.

uint32_t lv_snapshot_buf_size_needed(lv_obj_t *obj, lv_img_cf_t cf)

Get the buffer needed for object snapshot image.

Parameters
  • obj -- The object to generate snapshot.

  • cf -- color format for generated image.

Returns

the buffer size needed in bytes

lv_res_t lv_snapshot_take_to_buf(lv_obj_t *obj, lv_img_cf_t cf, lv_img_dsc_t *dsc, void *buf, uint32_t buff_size)

Take snapshot for object with its children, save image info to provided buffer.

Parameters
  • obj -- The object to generate snapshot.

  • cf -- color format for generated image.

  • dsc -- image descriptor to store the image result.

  • buff -- the buffer to store image data.

  • buff_size -- provided buffer size in bytes.

Returns

LV_RES_OK on success, LV_RES_INV on error.