Snapshot
Snapshot provides an API to take a snapshot image for an LVGL Widget together with its children. The image will look exactly like the Widget on the display.
Usage
Simply call function lv_snapshot_take(widget, color_format) to generate
the image descriptor which can be used as an Image Widget's image source using
lv_image_set_src()
.
Note, only following color formats are supported at this time:
Freeing the Image
The memory lv_snapshot_take()
uses is dynamically allocated using
lv_draw_buf_create()
. Use lv_draw_buf_destroy()
to free the
memory it allocated.
The snapshot image which is the draw buffer returned by lv_snapshot_take()
normally won't be added to the cache because it can be drawn directly. So you don't need
to invalidate the cache by calling lv_image_cache_drop()
before destroying
the draw buffer.
The below code snippet demonstrates correct use of lv_snapshot_take()
:
void update_snapshot(lv_obj_t * widget, 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(widget, LV_COLOR_FORMAT_ARGB8888);
lv_image_set_src(img_snapshot, snapshot);
}
Using an Existing Buffer
If the snapshot needs to be updated repeatedly, or if the caller provides the draw buffer, use lv_snapshot_take_to_draw_buf(widget, color_format, draw_buf). In this case, the caller is responsible for creating and destroying the draw buffer.
If snapshot is generated successfully, the image descriptor is updated,
the image data will be stored to the provided draw_buf
, and the function will
return LV_RESULT_OK
.
Note that snapshot may fail if the provided buffer is not large enough, which can happen if the Widget's size changes. It's recommended to use lv_snapshot_reshape_draw_buf(widget, draw_buf) to first ensure the buffer is large enough, and if it fails, destroy the existing draw buffer and call lv_snapshot_take directly.
Example
Simple snapshot example
C code
View on 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_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