Snapshot¶
Snapshot provides APIs to take snapshot image for LVGL object together with its children. The image will look exactly like the object.
Usage¶
Simply call API lv_snapshot_take
to generate the image descriptor which can be set as image object src using lv_img_set_src
.
Note, only below color formats are supported for now:
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
Free the Image¶
The memory lv_snapshot_take
uses are dynamically allocated using lv_mem_alloc
. Use API lv_snapshot_free
to free the memory it takes. This will firstly free memory the image data takes, then the image descriptor.
Take caution to free the snapshot but not delete the image object. Before free the memory, be sure to firstly unlink it from image object, using lv_img_set_src(NULL)
and lv_img_cache_invalidate_src(src)
.
Below code snippet explains usage of this 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);
}
Use Existing Buffer¶
If the snapshot needs update now and then, or simply caller provides memory, use 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);
for this case. It's caller's responsibility to alloc/free the memory.
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_buf_size_needed
to check the needed buffer size in byte firstly and resize the buffer accordingly.
Example¶
Simple snapshot example¶
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
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.