App:Library:LVGL:docs:Overview:Images
https://docs.lvgl.io/8.2/overview/image.html
Images
英文 | 自動翻訳 |
---|---|
An image can be a file or a variable which stores the bitmap itself and some metadata. |
Store images
英文 | 自動翻訳 |
---|---|
You can store images in two places
|
Variables
英文 | 自動翻訳 |
---|---|
Images stored internally in a variable are composed mainly of an
These are usually stored within a project as C files. They are linked into the resulting executable like any other constant data. |
Files
英文 | 自動翻訳 |
---|---|
To deal with files you need to add a storage Drive to LVGL. In short, a Drive is a collection of functions (open, read, close, etc.) registered in LVGL to make file operations. You can add an interface to a standard file system (FAT32 on SD card) or you create your simple file system to read data from an SPI Flash memory. In every case, a Drive is just an abstraction to read and/or write data to memory. See the File system section to learn more. Images stored as files are not linked into the resulting executable, and must be read into RAM before being drawn. As a result, they are not as resource-friendly as images linked at compile time. However, they are easier to replace without needing to rebuild the main program. |
Color formats
英文 | 自動翻訳 |
---|---|
Various built-in color formats are supported:
The bytes of For 32-bit color depth:
For 16-bit color depth:
For 8-bit color depth:
You can store images in a Raw format to indicate that it's not encoded with one of the built-in color formats and an external Image decoder needs to be used to decode the image.
|
Add and use images
英文 | 自動翻訳 |
---|---|
You can add images to LVGL in two ways:
|
Online converter
英文 | 自動翻訳 |
---|---|
The online Image converter is available here: https://lvgl.io/tools/imageconverter Adding an image to LVGL via the online converter is easy.
In the generated C arrays (variables), bitmaps for all the color depths (1, 8, 16 or 32) are included in the C file, but only the color depth that matches In the case of binary files, you need to specify the color format you want:
|
Manually create an image
英文 | 自動翻訳 |
---|---|
If you are generating an image at run-time, you can craft an image variable to display it using LVGL. For example: uint8_t my_img_data[] = {0x00, 0x01, 0x02, ...}; static lv_img_dsc_t my_img_dsc = { .header.always_zero = 0, .header.w = 80, .header.h = 60, .data_size = 80 * 60 * LV_COLOR_DEPTH / 8, .header.cf = LV_IMG_CF_TRUE_COLOR, /*Set the color format*/ .data = my_img_data, }; If the color format is Another (possibly simpler) option to create and display an image at run-time is to use the Canvas object. |
Use images
英文 | 自動翻訳 |
---|---|
The simplest way to use an image in LVGL is to display it with an lv_img object: lv_obj_t * icon = lv_img_create(lv_scr_act(), NULL); /*From variable*/ lv_img_set_src(icon, &my_icon_dsc); /*From file*/ lv_img_set_src(icon, "S:my_icon.bin"); If the image was converted with the online converter, you should use |
Image decoder
英文 | 自動翻訳 |
---|---|
As you can see in the Color formats section, LVGL supports several built-in image formats. In many cases, these will be all you need. LVGL doesn't directly support, however, generic image formats like PNG or JPG. To handle non-built-in image formats, you need to use external libraries and attach them to LVGL via the Image decoder interface. An image decoder consists of 4 callbacks:
You can add any number of image decoders. When an image needs to be drawn, the library will try all the registered image decoders until it finds one which can open the image, i.e. one which knows that format. The Custom image formatsThe easiest way to create a custom image is to use the online image converter and select
After decoding, the raw formats are considered True color by the library. In other words, the image decoder must decode the Raw images to True color according to the format described in the Color formats section. If you want to create a custom image, you should use With User encoded formats, the color format in the open function ( |
Register an image decoder
英文 | 自動翻訳 |
---|---|
Here's an example of getting LVGL to work with PNG images. First, you need to create a new image decoder and set some functions to open/close the PNG files. It should look like this: /*Create a new decoder and register functions */ lv_img_decoder_t * dec = lv_img_decoder_create(); lv_img_decoder_set_info_cb(dec, decoder_info); lv_img_decoder_set_open_cb(dec, decoder_open); lv_img_decoder_set_close_cb(dec, decoder_close); /** * Get info about a PNG image * @param decoder pointer to the decoder where this function belongs * @param src can be file name or pointer to a C array * @param header store the info here * @return LV_RES_OK: no error; LV_RES_INV: can't get the info */ static lv_res_t decoder_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header) { /*Check whether the type `src` is known by the decoder*/ if(is_png(src) == false) return LV_RES_INV; /* Read the PNG header and find `width` and `height` */ ... header->cf = LV_IMG_CF_RAW_ALPHA; header->w = width; header->h = height; } /** * Open a PNG image and return the decided image * @param decoder pointer to the decoder where this function belongs * @param dsc pointer to a descriptor which describes this decoding session * @return LV_RES_OK: no error; LV_RES_INV: can't get the info */ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) { /*Check whether the type `src` is known by the decoder*/ if(is_png(src) == false) return LV_RES_INV; /*Decode and store the image. If `dsc->img_data` is `NULL`, the `read_line` function will be called to get the image data line-by-line*/ dsc->img_data = my_png_decoder(src); /*Change the color format if required. For PNG usually 'Raw' is fine*/ dsc->header.cf = LV_IMG_CF_... /*Call a built in decoder function if required. It's not required if`my_png_decoder` opened the image in true color format.*/ lv_res_t res = lv_img_decoder_built_in_open(decoder, dsc); return res; } /** * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`. * Required only if the "open" function can't open the whole decoded pixel array. (dsc->img_data == NULL) * @param decoder pointer to the decoder the function associated with * @param dsc pointer to decoder descriptor * @param x start x coordinate * @param y start y coordinate * @param len number of pixels to decode * @param buf a buffer to store the decoded pixels * @return LV_RES_OK: ok; LV_RES_INV: failed */ lv_res_t decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) { /*With PNG it's usually not required*/ /*Copy `len` pixels from `x` and `y` coordinates in True color format to `buf` */ } /** * Free the allocated resources * @param decoder pointer to the decoder where this function belongs * @param dsc pointer to a descriptor which describes this decoding session */ static void decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) { /*Free all allocated data*/ /*Call the built-in close function if the built-in open/read_line was used*/ lv_img_decoder_built_in_close(decoder, dsc); } So in summary:
|
Manually use an image decoder
英文 | 自動翻訳 |
---|---|
LVGL will use registered image decoders automatically if you try and draw a raw image (i.e. using the The lv_res_t res; lv_img_decoder_dsc_t dsc; res = lv_img_decoder_open(&dsc, &my_img_dsc, color, frame_id); if(res == LV_RES_OK) { /*Do something with `dsc->img_data`*/ lv_img_decoder_close(&dsc); } |
Image caching
英文 | 自動翻訳 |
---|---|
Sometimes it takes a lot of time to open an image. Continuously decoding a PNG image or loading images from a slow external memory would be inefficient and detrimental to the user experience. Therefore, LVGL caches a given number of images. Caching means some images will be left open, hence LVGL can quickly access them from Of course, caching images is resource intensive as it uses more RAM to store the decoded image. LVGL tries to optimize the process as much as possible (see below), but you will still need to evaluate if this would be beneficial for your platform or not. Image caching may not be worth it if you have a deeply embedded target which decodes small images from a relatively fast storage medium. |
Cache size
英文 | 自動翻訳 |
---|---|
The number of cache entries can be defined with The size of the cache can be changed at run-time with |
Value of images
英文 | 自動翻訳 |
---|---|
When you use more images than cache entries, LVGL can't cache all the images. Instead, the library will close one of the cached images to free space. To decide which image to close, LVGL uses a measurement it previously made of how long it took to open the image. Cache entries that hold slower-to-open images are considered more valuable and are kept in the cache as long as possible. If you want or need to override LVGL's measurement, you can manually set the time to open value in the decoder open function in Every cache entry has a "life" value. Every time an image is opened through the cache, the life value of all entries is decreased to make them older. When a cached image is used, its life value is increased by the time to open value to make it more alive. If there is no more space in the cache, the entry with the lowest life value will be closed. |
Memory usage
英文 | 自動翻訳 |
---|---|
Note that a cached image might continuously consume memory. For example, if three PNG images are cached, they will consume memory while they are open. Therefore, it's the user's responsibility to be sure there is enough RAM to cache even the largest images at the same time. |
Clean the cache
英文 | 自動翻訳 |
---|---|
Let's say you have loaded a PNG image into a To do this, use |
API
Image buffer
英文 | 自動翻訳 |
---|---|
Typedefs typedef uint8_t lv_img_cf_t Enums enum [anonymous]
Functions lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_color_t color)
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y)
void lv_img_buf_set_px_color(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_color_t c)
void lv_img_buf_set_px_alpha(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa)
void lv_img_buf_set_palette(lv_img_dsc_t *dsc, uint8_t id, lv_color_t c)
void lv_img_buf_free(lv_img_dsc_t *dsc)
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
void _lv_img_buf_transform_init(lv_img_transform_dsc_t *dsc)
bool _lv_img_buf_transform_anti_alias(lv_img_transform_dsc_t *dsc)
bool _lv_img_buf_transform(lv_img_transform_dsc_t *dsc, lv_coord_t x, lv_coord_t y)
void _lv_img_buf_get_transformed_area(lv_area_t *res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom, const lv_point_t *pivot)
struct lv_img_header_t
struct lv_img_header_t
struct lv_img_dsc_t
struct lv_img_transform_dsc_t
|