mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
feat(snapshot) add API to take snapshot for object (#2353)
* Fix image zooming causes unexpected object size. Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com> * add lv_snapshot_take API. * fix(img) invalidate size and layout on zoom and angle change * fix(img) not self-repeating under some zoom level. * fix(snapshot) fix to keep the original position * Move various set_px_cb_xx functions to lv_hal_disp.c * add snapshot API to store image to provided buffer * minor fixes and refactoring * Move snapshot source to extra/others/snapshot. 1. Update parameter buff to buf. 2. Add macro to disable lv_snapshot, enabled by default. * docs(others) add the others folder with snapshot.md * docs(snapshot) added doc and example for snapshot. 1. Update doc snapshot.md 2. Add example lv_example_snapshot_1 to folder examples/others/snapshot 3. Update lv_conf_template.h and lv_conf_internal.h 4. Remove lv_snapshot.c from lv_misc.mk 5. Add others to index.md Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com> * add micropython example for snapshot Co-authored-by: Xu Xingliang <xuxingliang@xiaomi.com> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
parent
690b3546d6
commit
c98c8252ea
@ -34,6 +34,7 @@ PDF version: :download:`LVGL.pdf <LVGL.pdf>`
|
||||
overview/index
|
||||
widgets/index
|
||||
layouts/index
|
||||
others/index
|
||||
CONTRIBUTING
|
||||
CHANGELOG
|
||||
ROADMAP
|
||||
|
16
docs/others/index.md
Normal file
16
docs/others/index.md
Normal file
@ -0,0 +1,16 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/others/index.md
|
||||
```
|
||||
# Others
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
snapshot
|
||||
|
||||
```
|
||||
|
67
docs/others/snapshot.md
Normal file
67
docs/others/snapshot.md
Normal file
@ -0,0 +1,67 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/others/snapshot.md
|
||||
```
|
||||
# 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.
|
||||
|
||||
```c
|
||||
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
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/others/snapshot/index.rst
|
||||
|
||||
```
|
||||
## API
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_snapshot.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
@ -218,3 +218,5 @@ In both cases ORed state values can be used as well. E.g. `lv_obj_add_state(obj,
|
||||
|
||||
To learn more about the states read the related section of the [Style overview](/overview/style).
|
||||
|
||||
## Snapshot
|
||||
A snapshot image could be generated for object together with its children. Check details in [Snapshot](/others/snapshot).
|
||||
|
@ -23,6 +23,7 @@ extern "C" {
|
||||
#include "anim/lv_example_anim.h"
|
||||
#include "event/lv_example_event.h"
|
||||
#include "styles/lv_example_style.h"
|
||||
#include "others/lv_example_others.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
37
examples/others/lv_example_others.h
Normal file
37
examples/others/lv_example_others.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @file lv_example_others.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EXAMPLE_OTHERS_H
|
||||
#define LV_EXAMPLE_OTHERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "snapshot/lv_example_snapshot.h"
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EX_OTHERS_H*/
|
8
examples/others/snapshot/index.rst
Normal file
8
examples/others/snapshot/index.rst
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
Simple snapshot example
|
||||
"""""""""""""""""""
|
||||
|
||||
.. lv_example:: others/snapshot/lv_example_snapshot_1
|
||||
:language: c
|
||||
|
||||
|
38
examples/others/snapshot/lv_example_snapshot.h
Normal file
38
examples/others/snapshot/lv_example_snapshot.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file lv_example_snapshot.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_SNAPSHOT_H
|
||||
#define LV_EX_SNAPSHOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_example_snapshot_1(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EX_GET_STARTED_H*/
|
57
examples/others/snapshot/lv_example_snapshot_1.c
Normal file
57
examples/others/snapshot/lv_example_snapshot_1.c
Normal file
@ -0,0 +1,57 @@
|
||||
#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);
|
||||
|
||||
/*Create the container and its children*/
|
||||
lv_obj_t * container = lv_obj_create(root);
|
||||
|
||||
lv_obj_align(container, LV_ALIGN_CENTER, 0, 0);
|
||||
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
|
70
examples/others/snapshot/lv_example_snapshot_1.py
Normal file
70
examples/others/snapshot/lv_example_snapshot_1.py
Normal file
@ -0,0 +1,70 @@
|
||||
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 img_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)
|
@ -214,6 +214,9 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#define LV_USE_SNAPSHOT 1
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
1
lvgl.h
1
lvgl.h
@ -70,6 +70,7 @@ extern "C" {
|
||||
#include "src/extra/widgets/lv_widgets.h"
|
||||
#include "src/extra/layouts/lv_layouts.h"
|
||||
#include "src/extra/themes/lv_themes.h"
|
||||
#include "src/extra/others/lv_others.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
38
src/extra/others/lv_others.h
Normal file
38
src/extra/others/lv_others.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file lv_others.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OTHERS_H
|
||||
#define LV_OTHERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "snapshot/lv_snapshot.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OTHERS_H*/
|
213
src/extra/others/snapshot/lv_snapshot.c
Normal file
213
src/extra/others/snapshot/lv_snapshot.c
Normal file
@ -0,0 +1,213 @@
|
||||
/**
|
||||
* @file lv_snapshot.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_snapshot.h"
|
||||
#if LV_USE_SNAPSHOT
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../../../core/lv_disp.h"
|
||||
#include "../../../core/lv_refr.h"
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/** Get the buffer needed for object snapshot image.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return the buffer size needed in bytes
|
||||
*/
|
||||
uint32_t lv_snapshot_buf_size_needed(lv_obj_t * obj, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv_obj_update_layout(obj);
|
||||
|
||||
/*Width and height determine snapshot image size.*/
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
|
||||
uint8_t px_size = lv_img_cf_get_px_size(cf);
|
||||
return w * h * ((px_size + 7) >> 3);
|
||||
}
|
||||
|
||||
/** Take snapshot for object with its children, save image info to provided buffer.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
* @param dsc image descriptor to store the image result.
|
||||
* @param buf the buffer to store image data.
|
||||
* @param buff_size provided buffer size in bytes.
|
||||
*
|
||||
* @return LV_RES_OK on success, LV_RES_INV on error.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
LV_ASSERT(dsc);
|
||||
LV_ASSERT(buf);
|
||||
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
break;
|
||||
default:
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(lv_snapshot_buf_size_needed(obj, cf) > buff_size)
|
||||
return LV_RES_INV;
|
||||
|
||||
/*Width and height determine snapshot image size.*/
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
|
||||
/*Backup obj original info.*/
|
||||
lv_disp_t * disp_old = lv_obj_get_disp(obj);
|
||||
lv_obj_t * parent_old = lv_obj_get_parent(obj);
|
||||
|
||||
lv_memset(buf, 0x00, buff_size);
|
||||
lv_memset_00(dsc, sizeof(lv_img_dsc_t));
|
||||
|
||||
/*We are safe to use stack for below variables since disp will be
|
||||
* unregistered when function returns. */
|
||||
lv_disp_t * disp;
|
||||
lv_disp_drv_t driver;
|
||||
lv_disp_draw_buf_t draw_buf;
|
||||
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, w * h);
|
||||
|
||||
lv_disp_drv_init(&driver);
|
||||
driver.draw_buf = &draw_buf;
|
||||
driver.hor_res = lv_disp_get_hor_res(disp_old);
|
||||
driver.ver_res = lv_disp_get_ver_res(disp_old);
|
||||
lv_disp_drv_use_generic_set_px_cb(&driver, cf);
|
||||
|
||||
disp = lv_disp_drv_register(&driver);
|
||||
if(disp == NULL) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*Make background transparent */
|
||||
lv_disp_set_bg_opa(disp, LV_OPA_TRANSP);
|
||||
|
||||
/*Move obj to newly created disp and refresh it. */
|
||||
lv_obj_t * screen = lv_disp_get_scr_act(disp);
|
||||
lv_obj_remove_style_all(screen);
|
||||
lv_obj_allocate_spec_attr(screen);
|
||||
screen->spec_attr->child_cnt = 1;
|
||||
screen->spec_attr->children = &obj;
|
||||
|
||||
obj->parent = screen;
|
||||
|
||||
disp->inv_p = 0;
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
/*Don't call lv_refr_now to avoid animation disruption */
|
||||
_lv_disp_refr_timer(disp->refr_timer);
|
||||
|
||||
/*Restore obj original parameters and clean up*/
|
||||
obj->parent = parent_old;
|
||||
screen->spec_attr->child_cnt = 0;
|
||||
screen->spec_attr->children = NULL;
|
||||
|
||||
lv_disp_remove(disp);
|
||||
|
||||
dsc->data = buf;
|
||||
dsc->header.w = w;
|
||||
dsc->header.h = h;
|
||||
dsc->header.cf = cf;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/** Take snapshot for object with its children, alloc the memory needed.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return a pointer to a image descriptor, or NULL if failed.
|
||||
*/
|
||||
lv_img_dsc_t * lv_snapshot_take(lv_obj_t * obj, lv_img_cf_t cf)
|
||||
{
|
||||
uint32_t buff_size = lv_snapshot_buf_size_needed(obj, cf);
|
||||
|
||||
void * buf = lv_mem_alloc(buff_size);
|
||||
if(buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_img_dsc_t * dsc = lv_mem_alloc(sizeof(lv_img_dsc_t));
|
||||
if(dsc == NULL) {
|
||||
lv_mem_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(lv_snapshot_take_to_buf(obj, cf, dsc, buf, buff_size) == LV_RES_INV) {
|
||||
lv_mem_free(buf);
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dsc;
|
||||
}
|
||||
|
||||
/** Free the snapshot image returned by @ref lv_snapshot_take
|
||||
*
|
||||
* It will firstly free the data image takes, then the image descriptor.
|
||||
*
|
||||
* @param dsc The image descriptor generated by lv_snapshot_take.
|
||||
*
|
||||
*/
|
||||
void lv_snapshot_free(lv_img_dsc_t * dsc)
|
||||
{
|
||||
if(!dsc)
|
||||
return;
|
||||
|
||||
if(dsc->data)
|
||||
lv_mem_free((void *)dsc->data);
|
||||
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_SNAPSHOT*/
|
84
src/extra/others/snapshot/lv_snapshot.h
Normal file
84
src/extra/others/snapshot/lv_snapshot.h
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file lv_snapshot.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_SNAPSHOT_H
|
||||
#define LV_SNAPSHOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#include "../../../core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_SNAPSHOT
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/** Take snapshot for object with its children.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return a pointer to a image descriptor, or NULL if failed.
|
||||
*/
|
||||
lv_img_dsc_t * lv_snapshot_take(lv_obj_t * obj, lv_img_cf_t cf);
|
||||
|
||||
/** Free the snapshot image returned by @ref lv_snapshot_take
|
||||
*
|
||||
* It will firstly free the data image takes, then the image descriptor.
|
||||
*
|
||||
* @param dsc The image descriptor generated by lv_snapshot_take.
|
||||
*
|
||||
*/
|
||||
void lv_snapshot_free(lv_img_dsc_t * dsc);
|
||||
|
||||
/** Get the buffer needed for object snapshot image.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return the buffer size needed in bytes
|
||||
*/
|
||||
uint32_t lv_snapshot_buf_size_needed(lv_obj_t * obj, lv_img_cf_t cf);
|
||||
|
||||
/** Take snapshot for object with its children, save image info to provided buffer.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
* @param dsc image descriptor to store the image result.
|
||||
* @param buff the buffer to store image data.
|
||||
* @param buff_size provided buffer size in bytes.
|
||||
*
|
||||
* @return LV_RES_OK on success, LV_RES_INV on error.
|
||||
*/
|
||||
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);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#endif /*LV_USE_SNAPSHOT*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif
|
@ -34,6 +34,24 @@
|
||||
**********************/
|
||||
static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_data);
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@ -403,6 +421,29 @@ lv_disp_rot_t lv_disp_get_rotation(lv_disp_t * disp)
|
||||
return disp->driver->rotated;
|
||||
}
|
||||
|
||||
void lv_disp_drv_use_generic_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
disp_drv->set_px_cb = set_px_true_color_alpha;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha1;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha2;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha4;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha8;
|
||||
break;
|
||||
default:
|
||||
disp_drv->set_px_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -413,3 +454,99 @@ static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_d
|
||||
lv_obj_mark_layout_as_dirty(obj);
|
||||
return LV_OBJ_TREE_WALK_NEXT;
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_1BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_2BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_4BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_8BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
d->header.always_zero = 0;
|
||||
d->header.h = 1; /*Doesn't matter*/
|
||||
|
||||
uint8_t br = lv_color_brightness(color);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
uint8_t bg = lv_img_buf_get_px_alpha(d, x, y);
|
||||
br = (uint16_t)((uint16_t)br * opa + (bg * (255 - opa))) >> 8;
|
||||
}
|
||||
|
||||
lv_img_buf_set_px_alpha(d, x, y, br);
|
||||
}
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.always_zero = 0;
|
||||
d.header.h = 1; /*Doesn't matter*/;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
|
||||
lv_color_t bg_color = lv_img_buf_get_px_color(&d, x, y, lv_color_black());
|
||||
lv_opa_t bg_opa = lv_img_buf_get_px_alpha(&d, x, y);
|
||||
|
||||
lv_opa_t res_opa;
|
||||
lv_color_t res_color;
|
||||
|
||||
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &res_opa);
|
||||
|
||||
lv_img_buf_set_px_alpha(&d, x, y, res_opa);
|
||||
lv_img_buf_set_px_color(&d, x, y, res_color);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../draw/lv_img_buf.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_ll.h"
|
||||
@ -312,6 +313,8 @@ lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
|
||||
*/
|
||||
lv_disp_draw_buf_t * lv_disp_get_draw_buf(lv_disp_t * disp);
|
||||
|
||||
void lv_disp_drv_use_generic_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -585,6 +585,15 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#endif
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#ifndef LV_USE_SNAPSHOT
|
||||
# ifdef CONFIG_LV_USE_SNAPSHOT
|
||||
# define LV_USE_SNAPSHOT CONFIG_LV_USE_SNAPSHOT
|
||||
# else
|
||||
# define LV_USE_SNAPSHOT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
@ -27,25 +27,6 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_canvas_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void set_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf);
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -595,7 +576,7 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@ -656,7 +637,7 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing();
|
||||
_lv_refr_set_disp_refreshing(&disp);
|
||||
@ -717,7 +698,7 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing();
|
||||
_lv_refr_set_disp_refreshing(&disp);
|
||||
@ -764,7 +745,7 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@ -822,7 +803,7 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@ -878,7 +859,7 @@ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@ -930,123 +911,4 @@ static void lv_canvas_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
}
|
||||
|
||||
static void set_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
disp_drv->set_px_cb = set_px_true_color_alpha;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha1;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha2;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha4;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha8;
|
||||
break;
|
||||
default:
|
||||
disp_drv->set_px_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_1BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_2BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_4BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_8BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
d->header.always_zero = 0;
|
||||
d->header.h = 1; /*Doesn't matter*/
|
||||
|
||||
uint8_t br = lv_color_brightness(color);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
uint8_t bg = lv_img_buf_get_px_alpha(d, x, y);
|
||||
br = (uint16_t)((uint16_t)br * opa + (bg * (255 - opa))) >> 8;
|
||||
}
|
||||
|
||||
lv_img_buf_set_px_alpha(d, x, y, br);
|
||||
}
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.always_zero = 0;
|
||||
d.header.h = 1; /*Doesn't matter*/;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
|
||||
lv_color_t bg_color = lv_img_buf_get_px_color(&d, x, y, lv_color_black());
|
||||
lv_opa_t bg_opa = lv_img_buf_get_px_alpha(&d, x, y);
|
||||
|
||||
lv_opa_t res_opa;
|
||||
lv_color_t res_color;
|
||||
|
||||
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &res_opa);
|
||||
|
||||
lv_img_buf_set_px_alpha(&d, x, y, res_opa);
|
||||
lv_img_buf_set_px_color(&d, x, y, res_color);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user