基本函数解析
路径:lvgl/src/others/snapshot/lv_snapshot.c
lv_snapshot_take
快照提供API来为LVGL对象及其子对象生成快照图像。该图像将与显示上的对象完全一致。
/*
*@params obj 要创建快照的obj
*@params cf 颜色格式
**/
lv_draw_buf_t * lv_snapshot_take(lv_obj_t * obj, lv_color_format_t cf)
{
LV_ASSERT_NULL(obj);
//先创建一个buffer,用于存储截图
lv_draw_buf_t * draw_buf = lv_snapshot_create_draw_buf(obj, cf);
if(draw_buf == NULL) return NULL;
//通过obj 获取信息,开始截图
if(lv_snapshot_take_to_draw_buf(obj, cf, draw_buf) != LV_RESULT_OK) {
lv_draw_buf_destroy(draw_buf);
return NULL;
}
return draw_buf;
}
参数:
- obj 被快照的对象
- cf 颜色格式 目前支持以下几种:
- LV_COLOR_FORMATE_RGB565
- LV_COLOR_FORMATE_RGB888
- LV_COLOR_FORMATE_XRRGB888
- LV_COLOR_FORMATE_ARGB888
lv_snapshot_create_draw_buf
根据obj的尺寸,创建 draw_buf
/*
*@params obj 要创建快照的obj
*@params cf 颜色格式
**/
lv_draw_buf_t * lv_snapshot_create_draw_buf(lv_obj_t * obj, lv_color_format_t cf)
{
lv_obj_update_layout(obj);
int32_t w = lv_obj_get_width(obj);
int32_t h = lv_obj_get_height(obj);
int32_t ext_size = _lv_obj_get_ext_draw_size(obj);
w += ext_size * 2;
h += ext_size * 2;
if(w == 0 || h == 0) return NULL;
return lv_draw_buf_create(w, h, cf, LV_STRIDE_AUTO);
}
lv_snapshot_take_to_draw_buf
将创建的 draw_buf进行复制,将obj绘制到layer的draw_buffer中
/*
*@params obj 要创建快照的obj指针
*@params cf 颜色格式
*@params draw_buf 将快照保存到哪个缓冲区
**/
lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, lv_draw_buf_t * draw_buf)
{
LV_ASSERT_NULL(obj);//断言 判断obj非空
LV_ASSERT_NULL(draw_buf);//断言 判断buffer非空
lv_result_t res;
switch(cf) {
case LV_COLOR_FORMAT_RGB565:
case LV_COLOR_FORMAT_RGB888:
case LV_COLOR_FORMAT_XRGB8888:
case LV_COLOR_FORMAT_ARGB8888:
break;
default:
LV_LOG_WARN("Not supported color format");
return LV_RESULT_INVALID;
}
//判断draw_buf的size是否足够绘制新的图形
res = lv_snapshot_reshape_draw_buf(obj, draw_buf);
if(res != LV_RESULT_OK) return res;
/* clear draw buffer*/
lv_draw_buf_clear(draw_buf, NULL);
lv_area_t snapshot_area;
int32_t w = draw_buf->header.w;
int32_t h = draw_buf->header.h;
int32_t ext_size = _lv_obj_get_ext_draw_size(obj);
//从obj中获取信息存入snapshot_area中
lv_obj_get_coords(obj, &snapshot_area);
lv_area_increase(&snapshot_area, ext_size, ext_size);
//新建一个临时图层,用于存快照数据
lv_layer_t layer;
lv_memzero(&layer, sizeof(layer));
//设置临时图层的各种属性
layer.draw_buf = draw_buf;
layer.buf_area.x1 = snapshot_area.x1;
layer.buf_area.y1 = snapshot_area.y1;
layer.buf_area.x2 = snapshot_area.x1 + w - 1;
layer.buf_area.y2 = snapshot_area.y1 + h - 1;
layer.color_format = cf;
layer._clip_area = snapshot_area;
//获取正在刷新的对象
lv_display_t * disp_old = _lv_refr_get_disp_refreshing();
lv_display_t * disp_new = lv_obj_get_display(obj);//获取屏幕刷新对象
lv_layer_t * layer_old = disp_new->layer_head;
disp_new->layer_head = &layer;
//设置新的刷新对象
_lv_refr_set_disp_refreshing(disp_new);
lv_obj_redraw(&layer, obj);//前几篇有介绍
//等待所有绘制任务完成
while(layer.draw_task_head) {
lv_draw_dispatch_wait_for_request();
lv_draw_dispatch_layer(NULL, &layer);
}
//重置图层的头部
disp_new->layer_head = layer_old;
//恢复当前刷新的显示设备
_lv_refr_set_disp_refreshing(disp_old);
return LV_RESULT_OK;
}
lv_snapshot_reshape_draw_buf
- 判断draw_buf的size是否足够绘制新的图形
lv_result_t lv_snapshot_reshape_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf)
lv_obj_get_coords
- 将从obj或者的area信息存入 coords中
void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * coords)
_lv_refr_get_disp_refreshing
- 获取正在刷新的显示对象
_lv_refr_set_disp_refreshing(lv_display_t * disp)
- 设置正在刷新的显示对象