mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-31 07:56:23 +08:00
docs(images): remove outdated information and reorganize image docs (#9221)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -145,7 +145,7 @@ are needed to build packages or to run the build system itself. It may contain
|
|||||||
compilers, build tools, and libraries that are required to support the build
|
compilers, build tools, and libraries that are required to support the build
|
||||||
process for the target.
|
process for the target.
|
||||||
|
|
||||||
.. _images:
|
.. _rpi4_images:
|
||||||
|
|
||||||
images
|
images
|
||||||
======
|
======
|
||||||
@@ -181,7 +181,7 @@ If it is mounted on /dev/sda, run the following command
|
|||||||
|
|
||||||
sudo dd if=images/sdcard.img of=/dev/sda
|
sudo dd if=images/sdcard.img of=/dev/sda
|
||||||
|
|
||||||
As mentioned in :ref:`images`, the output image is in ``images`` and named
|
As mentioned in :ref:`rpi4_images`, the output image is in ``images`` and named
|
||||||
``sdcard.img``.
|
``sdcard.img``.
|
||||||
|
|
||||||
Connect an Ethernet cable to the RPi4 and ensure the laptop and the RPi4 are on
|
Connect an Ethernet cable to the RPi4 and ensure the laptop and the RPi4 are on
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
.. include:: /include/external_links.txt
|
||||||
.. _bmp:
|
.. _bmp:
|
||||||
|
|
||||||
===========
|
===========
|
||||||
@@ -6,18 +7,16 @@ BMP Decoder
|
|||||||
|
|
||||||
This BMP Decoder utility allows you to use images from .BMP files in LVGL.
|
This BMP Decoder utility allows you to use images from .BMP files in LVGL.
|
||||||
|
|
||||||
Library source: https://github.com/caj-johnson/bmp-decoder
|
|
||||||
|
|
||||||
Instead of loading the whole image at once, BMP pixels are read on demand,
|
Instead of loading the whole image at once, BMP pixels are read on demand,
|
||||||
so using BMP images requires very little RAM.
|
so using BMP images requires very little RAM.
|
||||||
|
|
||||||
If enabled in ``lv_conf.h`` by setting :c:macro:`LV_USE_BMP` to ``1``, LVGL will
|
If enabled in ``lv_conf.h`` by setting :c:macro:`LV_USE_BMP` to ``1``, LVGL will
|
||||||
register a new image decoder automatically so BMP files can be directly used as image
|
register the BMP image decoder automatically so BMP files can be directly used as
|
||||||
sources. Example:
|
image sources. Example:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_image_set_src(my_img, "S:path/to/picture.bmp");
|
lv_image_set_src(my_img, "S:path/to/picture.bmp");
|
||||||
|
|
||||||
Note that, a :ref:`file_system` driver needs to registered to open images from
|
Note that, a :ref:`file_system` driver needs to registered to open images from
|
||||||
files. Follow the instructions in :ref:`file_system`.
|
files. Follow the instructions in :ref:`file_system`.
|
||||||
@@ -29,15 +28,13 @@ files. Follow the instructions in :ref:`file_system`.
|
|||||||
Limitations
|
Limitations
|
||||||
***********
|
***********
|
||||||
|
|
||||||
- Only BMP files are supported. BMP images as C arrays
|
- Only uncompressed BMP files are supported. BMP images as C arrays
|
||||||
(:cpp:struct:`lv_image_dsc_t`) are not. This is because there is no practical
|
(:cpp:type:`lv_image_dsc_t`) are not supported. This is because there is no
|
||||||
differences between how the BMP files and LVGL's image format stores
|
practical difference between how uncompressed BMP files and LVGL's image format
|
||||||
the image data.
|
store the image data.
|
||||||
- BMP files can be loaded only from .BMP files. If you want to store them in
|
|
||||||
flash it's better to convert them to a C array with `LVGL's image converter <https://lvgl.io/tools/imageconverter>`__.
|
|
||||||
- The BMP file's color format needs to match the configured :c:macro:`LV_COLOR_DEPTH`
|
- The BMP file's color format needs to match the configured :c:macro:`LV_COLOR_DEPTH`
|
||||||
of the display on which it will be rendered. You can use GIMP to save the image
|
of the display on which it will be rendered. You can use GIMP to save the image
|
||||||
in the required format. Both RGB888 and ARGB888 works with
|
in the required format. Both RGB888 and ARGB888 work with
|
||||||
:c:macro:`LV_COLOR_DEPTH` ``32``
|
:c:macro:`LV_COLOR_DEPTH` ``32``
|
||||||
- Color palettes are not supported.
|
- Color palettes are not supported.
|
||||||
- Because the whole image is not loaded, it cannot be zoomed or rotated.
|
- Because the whole image is not loaded, it cannot be zoomed or rotated.
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Image Support
|
|||||||
libpng
|
libpng
|
||||||
lodepng
|
lodepng
|
||||||
libwebp
|
libwebp
|
||||||
|
lz4
|
||||||
rle
|
rle
|
||||||
rlottie
|
rlottie
|
||||||
svg
|
svg
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ It should be noted that each image decoded needs to consume:
|
|||||||
|
|
||||||
image width |times| image height |times| 3
|
image width |times| image height |times| 3
|
||||||
|
|
||||||
bytes of RAM, and it needs to be combined with the :ref:`overview_image_caching`
|
bytes of RAM, and it needs to be combined with the :ref:`image caching`
|
||||||
feature to ensure that the memory usage is within a reasonable range.
|
feature to ensure that the memory usage is within a reasonable range.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ It should be noted that each image of this decoder needs to consume
|
|||||||
|
|
||||||
width |times| height |times| 4
|
width |times| height |times| 4
|
||||||
|
|
||||||
bytes of RAM, and it needs to be combined with the :ref:`overview_image_caching` feature to
|
bytes of RAM, and it needs to be combined with the :ref:`image caching` feature to
|
||||||
ensure that the memory usage is within a reasonable range. The decoded image is
|
ensure that the memory usage is within a reasonable range. The decoded image is
|
||||||
stored in RGBA pixel format.
|
stored in RGBA pixel format.
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ Memory requirements for WebP images:
|
|||||||
- Lossy WebP: width × height × 4 bytes (ARGB8888 format)
|
- Lossy WebP: width × height × 4 bytes (ARGB8888 format)
|
||||||
- Lossless WebP: width × height × 4 bytes (ARGB8888 format)
|
- Lossless WebP: width × height × 4 bytes (ARGB8888 format)
|
||||||
|
|
||||||
For optimal memory usage, combine with LVGL's :ref:`overview_image_caching` feature.
|
For optimal memory usage, combine with LVGL's :ref:`image caching` feature.
|
||||||
|
|
||||||
.. _libwebp_example:
|
.. _libwebp_example:
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ bytes of RAM is required from the LVGL heap. The decoded image is stored in RGB
|
|||||||
pixel format.
|
pixel format.
|
||||||
|
|
||||||
Since it might take significant time to decode PNG images LVGL's
|
Since it might take significant time to decode PNG images LVGL's
|
||||||
:ref:`overview_image_caching` feature can be useful.
|
:ref:`image caching` feature can be useful.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
.. include:: /include/substitutions.txt
|
||||||
|
.. include:: /include/external_links.txt
|
||||||
|
.. include:: /include/custom_roles.txt
|
||||||
|
.. _lz4:
|
||||||
|
|
||||||
|
=================
|
||||||
|
LZ4 Decompression
|
||||||
|
=================
|
||||||
|
|
||||||
|
LVGL provides the extremely fast LZ4 decompression method found in the `LZ4
|
||||||
|
repository <https://github.com/lz4/lz4>`__ on GitHub. It can be used to reduce
|
||||||
|
binary image size. The LZ4 compression is a lossless compression method.
|
||||||
|
|
||||||
|
The LVGL's built-in binary image decoder supports LZ4-compressed images.
|
||||||
|
The decoder supports both variable and file as image sources. The original
|
||||||
|
binary data is directly decoded to RAM.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Which Library
|
||||||
|
*************
|
||||||
|
|
||||||
|
If ``LV_USE_LZ4_INTERNAL`` is enabled in ``lv_conf.h``, LVGL's internal copy of the
|
||||||
|
LZ4 decompression algorithm is used (``./src/libs/lz4/lz4.c``).
|
||||||
|
|
||||||
|
If ``LV_USE_LZ4_EXTERNAL`` is enabled, the LVGL project is assumed to be compiled and
|
||||||
|
linked with an external LZ4 library that provides the :cpp:func:`LZ4_decompress_safe`
|
||||||
|
function.
|
||||||
|
|
||||||
|
One of them must be enabled to use LZ4 decompression.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Benefits
|
||||||
|
********
|
||||||
|
|
||||||
|
LZ4 is best at compressing data where compression and decompression speed is a
|
||||||
|
priority over compression ratio, making it ideal for applications like real-time data
|
||||||
|
processing.
|
||||||
|
|
||||||
|
.. image:: /_static/images/lz4-compress-statistics.png
|
||||||
|
:alt: LZ4 compress statistics from lz4.org
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _lz4_usage:
|
||||||
|
|
||||||
|
Usage
|
||||||
|
*****
|
||||||
|
|
||||||
|
To use the LZ4 Decoder, enable it in ``lv_conf.h`` configuration file by setting
|
||||||
|
either ``LV_USE_LZ4_INTERNAL`` or ``LV_USE_LZ4_EXTERNAL`` to ``1``. LZ4 images can
|
||||||
|
then be used in the same way as other images.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_image_set_src(img, "path/to/cogwheel.bin");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Generating LZ4 Compressed Binary Images
|
||||||
|
***************************************
|
||||||
|
|
||||||
|
An LZ4 image binary can be directly generated from another image using script
|
||||||
|
``lvgl/scripts/LVGLImage.py``.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./scripts/LVGLImage.py --ofmt BIN --cf I8 --compress LZ4 cogwheel.png
|
||||||
|
|
||||||
|
This will decompress ``cogwheel.png``, and then re-compress it using LZ4 and write
|
||||||
|
the output to ``./output/cogwheel.bin``.
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ Image font
|
|||||||
Draw image in **label** or **span** obj with :cpp:type:`lv_imgfont`. This is often used to
|
Draw image in **label** or **span** obj with :cpp:type:`lv_imgfont`. This is often used to
|
||||||
display Unicode emoji icons in text.
|
display Unicode emoji icons in text.
|
||||||
|
|
||||||
Supported image formats: determined by enabled LVGL :ref:`image decoders <overview_image_decoder>`.
|
Supported image formats: determined by enabled LVGL :ref:`image decoders <image_decoders>`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,10 @@ Using these symbols is very simple:
|
|||||||
lv_label_set_text(label, LV_SYMBOL_OK "Apply"); /*Concatenate with a string*/
|
lv_label_set_text(label, LV_SYMBOL_OK "Apply"); /*Concatenate with a string*/
|
||||||
|
|
||||||
|
|
||||||
To add a new symbol in a custom font:
|
.. _font_adding_a_custom_symbol:
|
||||||
|
|
||||||
|
Adding a Custom Symbol
|
||||||
|
----------------------
|
||||||
|
|
||||||
1. Search for a symbol on https://fontawesome.com. For example the
|
1. Search for a symbol on https://fontawesome.com. For example the
|
||||||
`USB symbol <https://fontawesome.com/icons/usb?style=brands>`__. Copy its
|
`USB symbol <https://fontawesome.com/icons/usb?style=brands>`__. Copy its
|
||||||
@@ -165,7 +168,9 @@ To add a new symbol in a custom font:
|
|||||||
Make sure to compile the ``.c`` file of your font.
|
Make sure to compile the ``.c`` file of your font.
|
||||||
6. Declare the font using :cpp:expr:`LV_FONT_DECLARE(my_font_name)`.
|
6. Declare the font using :cpp:expr:`LV_FONT_DECLARE(my_font_name)`.
|
||||||
|
|
||||||
**Using the symbol**
|
|
||||||
|
Using Your Custom Symbol
|
||||||
|
------------------------
|
||||||
|
|
||||||
1. Convert the Unicode value to UTF8, for example on
|
1. Convert the Unicode value to UTF8, for example on
|
||||||
`this site <http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex>`__.
|
`this site <http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex>`__.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,122 @@
|
|||||||
|
.. include:: /include/external_links.txt
|
||||||
|
|
||||||
|
.. _adding images to your project:
|
||||||
|
|
||||||
|
=============================
|
||||||
|
Adding Images to Your Project
|
||||||
|
=============================
|
||||||
|
|
||||||
|
You can add images to LVGL in three ways:
|
||||||
|
|
||||||
|
- using the :ref:`online converter <images_online_converter>`
|
||||||
|
- using the :ref:`offline converter <images_offline_converter>`
|
||||||
|
- :ref:`manually create images <images_manually_creating>`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _images_online_converter:
|
||||||
|
|
||||||
|
Online Converter
|
||||||
|
****************
|
||||||
|
|
||||||
|
Adding an image to LVGL via the `LVGL Online Image Converter`_ is easy:
|
||||||
|
|
||||||
|
1. Click [Select image file(s)] and select a BMP, PNG, JPG, WEBP or SVG image.
|
||||||
|
Also supported: GIF, SVGZ, TIF, TIFF, AI, DRW, PCT, PSP, XCF, PSD, RAW and HEIC.
|
||||||
|
2. Select the :ref:`Color format <images_color_formats>`. Currently supported:
|
||||||
|
|
||||||
|
- RGB565
|
||||||
|
- RGB565A8
|
||||||
|
- RGB888
|
||||||
|
- XRGB8888
|
||||||
|
- ARGB8888
|
||||||
|
|
||||||
|
If you need another color format, use the :ref:`offline converter
|
||||||
|
<images_offline_converter>`.
|
||||||
|
|
||||||
|
.. note:: BMP images are currently supported in file form only.
|
||||||
|
See :ref:`images_bmp_files` below.
|
||||||
|
|
||||||
|
3. Click the [Convert] button. This will convert the file and open a "Save As..."
|
||||||
|
dialog box. The default filename will be the filename of the selected image file
|
||||||
|
with a ``.c`` extension.
|
||||||
|
|
||||||
|
In the case of binary (.bin) files, you need to specify the color format you want:
|
||||||
|
|
||||||
|
- RGB332 for 8-bit color depth
|
||||||
|
- RGB565 for 16-bit color depth
|
||||||
|
- RGB565 Swap for 16-bit color depth (two bytes are swapped)
|
||||||
|
- RGB888 for 24-bit color depth (8-bit channels without an alpha channel)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _images_offline_converter:
|
||||||
|
|
||||||
|
Offline Converter
|
||||||
|
*****************
|
||||||
|
|
||||||
|
The offline converter is contained in ``./scripts/LVGLImage.py``. Run it with no
|
||||||
|
arguments to see its command-line options.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _images_bmp_files:
|
||||||
|
|
||||||
|
BMP and WEBP Files
|
||||||
|
******************
|
||||||
|
|
||||||
|
Currently, support for BMP and WEBP images is limited to using them as files on an
|
||||||
|
external file system. For a BMP file, follow the instructions in :ref:`bmp`. For
|
||||||
|
WEBP files, follow the instructions in :ref:`libwebp`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _images_bin_files:
|
||||||
|
|
||||||
|
BIN Files
|
||||||
|
*********
|
||||||
|
|
||||||
|
Another way you can add an image to your project is by using the
|
||||||
|
:ref:`images_offline_converter` to create a ``.bin`` file. Typically, you would do
|
||||||
|
this with a target color format matching the Display the image is going to be sent
|
||||||
|
to. Optionally, you can use a command-line argument to cause the image contents to
|
||||||
|
be compressed using RLE or LZ4 compression as well. Of course, the decompression
|
||||||
|
logic must be part of your project by enabling appropriate ``LV_USE_RLE``,
|
||||||
|
``LV_USE_LZ4_INTERNAL``, and/or ``LV_USE_LZ4_EXTERNAL`` macros in your ``lv_conf.h``
|
||||||
|
file.
|
||||||
|
|
||||||
|
This enables the drawing logic to have a very low RAM footprint because the pixels
|
||||||
|
are extracted directly from the file similar to how they are extracted from BMP files.
|
||||||
|
|
||||||
|
See :ref:`rle` and :ref:`lz4`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _images_manually_creating:
|
||||||
|
|
||||||
|
Manually Creating an Image
|
||||||
|
**************************
|
||||||
|
|
||||||
|
If you are generating an image at run-time, you can craft an image
|
||||||
|
variable to display it using LVGL. For example:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
uint8_t my_img_data[] = {0x00, 0x01, 0x02, ...};
|
||||||
|
|
||||||
|
static lv_image_dsc_t my_img_dsc = {
|
||||||
|
.header.magic = LV_IMAGE_HEADER_MAGIC,
|
||||||
|
.header.cf = LV_COLOR_FORMAT_RGB565, /* Set color format */
|
||||||
|
.header.flags = 0,
|
||||||
|
.header.w = 80,
|
||||||
|
.header.h = 60,
|
||||||
|
.header.stride = 80 * LV_COLOR_DEPTH / 8,
|
||||||
|
.header.reserved_2 = 0,
|
||||||
|
.data_size = 80 * 60 * LV_COLOR_DEPTH / 8,
|
||||||
|
.data = my_img_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
Another (possibly simpler) option to create and display an image at
|
||||||
|
run-time is to use the :ref:`Canvas <lv_canvas>` Widget.
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
.. _image caching:
|
||||||
|
|
||||||
|
=============
|
||||||
|
Image Caching
|
||||||
|
=============
|
||||||
|
|
||||||
|
Sometimes it takes a lot of time to open an image. Repeatedly decoding
|
||||||
|
a PNG/JPEG image or loading images from a slow external memory would be
|
||||||
|
inefficient and detrimental to the user experience.
|
||||||
|
|
||||||
|
Therefore, LVGL caches image data. Caching means some
|
||||||
|
images will be left open, hence LVGL can quickly access them from
|
||||||
|
``dsc->decoded`` instead of needing to decode them again.
|
||||||
|
|
||||||
|
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 size of cache (in bytes) can be defined with
|
||||||
|
:c:macro:`LV_CACHE_DEF_SIZE` in *lv_conf.h*. The default value is 0, so
|
||||||
|
no image is cached.
|
||||||
|
|
||||||
|
The size of cache can be changed at run-time with
|
||||||
|
:cpp:expr:`lv_cache_set_max_size(size_t size)`,
|
||||||
|
and retrieved with :cpp:expr:`lv_cache_get_max_size()`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Value of Images
|
||||||
|
***************
|
||||||
|
|
||||||
|
When you use more images than available cache size, 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 an LRU (least-recently-used) algorithm.
|
||||||
|
Most-recently-used images are prioritized to keep in the cache as long as possible,
|
||||||
|
while the oldest (images not used recently) are disposed of to make room for new
|
||||||
|
cache content.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Invalidating Cache Entries
|
||||||
|
**************************
|
||||||
|
|
||||||
|
Let's say you have loaded a PNG image into a :cpp:struct:`lv_image_dsc_t` ``my_png``
|
||||||
|
variable and use it in an ``lv_image`` Widget. If the image is already
|
||||||
|
cached and you then change the underlying PNG file, you need to notify
|
||||||
|
LVGL to cache the image again. Otherwise, there is no easy way of
|
||||||
|
detecting that the underlying file has changed and LVGL will still draw the
|
||||||
|
old image from cache. To do this, use :cpp:expr:`lv_image_cache_drop(&my_png)`.
|
||||||
|
|
||||||
|
To invalidate all cached images: :cpp:expr:`lv_image_cache_drop(NULL)`.
|
||||||
|
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
.. include:: /include/external_links.txt
|
||||||
|
|
||||||
|
.. _images_color_formats:
|
||||||
|
|
||||||
|
=============
|
||||||
|
Color Formats
|
||||||
|
=============
|
||||||
|
|
||||||
|
Built-in Input Color Formats
|
||||||
|
****************************
|
||||||
|
|
||||||
|
The following image pixel color formats have built-in decoding support:
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
All of the below format names are used in code by prefixing them with
|
||||||
|
``LV_COLOR_FORMAT_`` (e.g. :cpp:enumerator:`LV_COLOR_FORMAT_RGB565`).
|
||||||
|
|
||||||
|
.. container:: tighter-table-3
|
||||||
|
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| Format | BPP | Supported | Description |
|
||||||
|
| | | by offline | |
|
||||||
|
| | | converter | |
|
||||||
|
+========================+=====+============+=================================================================+
|
||||||
|
| I1 [1]_ | 1 | Yes | Indexed with 2-color palette |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| I2 [1]_ | 2 | Yes | Indexed with 4-color palette |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| I4 [1]_ | 4 | Yes | Indexed with 16-color palette |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| I8 [1]_ | 8 | Yes | Indexed with 256-color palette |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| A8 | 8 | Yes | Pixels express alpha only (used where color is supplied |
|
||||||
|
| | | | elsewhere as with fonts) |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| L8 | 8 | Yes | Luminance: pixels express gray-scale value in range [0-255] |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| AL88 | 16 | Not yet | L8 with an alpha byte |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| RGB565 | 16 | Yes | Standard RGB565 (little-endian format) |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| ARGB8565 | 24 | Yes | RGB565 preceded by alpha byte |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| RGB565A8 | 24 | Yes | RGB565 + trailing alpha byte |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| RGB565_SWAPPED | 16 | Yes | RGB565 big-endian format |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| RGB888 | 24 | Yes | Standard RGB with 8 bits per color channel |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| ARGB8888 | 32 | Yes | Standard ARGB with 8 bits per color channel |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| XRGB8888 | 32 | Yes | Like ARGB but alpha bytes are ignored |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| ARGB8888_PREMULTIPLIED | 32 | Yes | ARGB8888 with RGB pre-darkened according to alpha channel value |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| RAW [2]_ | ? | n/a | See :ref:`custom_image_formats` |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
| RAW_ALPHA [2]_ | ? | n/a | See :ref:`custom_image_formats` |
|
||||||
|
+------------------------+-----+------------+-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
.. [1] I1, I2, I4 and I8 indexed formats require ``LV_DRAW_SW_SUPPORT_ARGB8888`` to
|
||||||
|
be configured to ``1`` in your ``lv_conf.h`` file. Palette colors are
|
||||||
|
always ``ARGB8888``.
|
||||||
|
|
||||||
|
.. [2] Custom formats can be supported by specifying one of the RAW color formats and
|
||||||
|
using an external :ref:`image decoder <image_decoders>` to decode it.
|
||||||
|
See :ref:`image_decoders`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Built-In Input and Output Formats
|
||||||
|
*********************************
|
||||||
|
|
||||||
|
+-------------------------+----------------+------------+-------------+
|
||||||
|
| Format | BPP | Supported | Description |
|
||||||
|
| | | by offline | |
|
||||||
|
| | | converter | |
|
||||||
|
+=========================+================+============+=============+
|
||||||
|
| NATIVE [3]_ | LV_COLOR_DEPTH | No | See below |
|
||||||
|
+-------------------------+----------------+------------+-------------+
|
||||||
|
| NATIVE_WITH_ALPHA [3]_ | LV_COLOR_DEPTH | No | See below |
|
||||||
|
+-------------------------+----------------+------------+-------------+
|
||||||
|
|
||||||
|
.. [3]
|
||||||
|
|
||||||
|
What they mean (from ``lv_color.h``):
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
#if LV_COLOR_DEPTH == 1
|
||||||
|
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_I1,
|
||||||
|
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_I1,
|
||||||
|
#elif LV_COLOR_DEPTH == 8
|
||||||
|
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_L8,
|
||||||
|
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_AL88,
|
||||||
|
#elif LV_COLOR_DEPTH == 16
|
||||||
|
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_RGB565,
|
||||||
|
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_RGB565A8,
|
||||||
|
#elif LV_COLOR_DEPTH == 24
|
||||||
|
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_RGB888,
|
||||||
|
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_ARGB8888,
|
||||||
|
#elif LV_COLOR_DEPTH == 32
|
||||||
|
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_XRGB8888,
|
||||||
|
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_ARGB8888,
|
||||||
|
#else
|
||||||
|
#error "LV_COLOR_DEPTH should be 1, 8, 16, 24 or 32"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GPU Input Formats
|
||||||
|
*****************
|
||||||
|
|
||||||
|
The following color formats are supported by certain GPUs and are retained as
|
||||||
|
color-format enumeration values that can be used when a GPU is going to be doing the
|
||||||
|
drawing.
|
||||||
|
|
||||||
|
|
||||||
|
Alpha-Only and Special ARGB Formats
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
| Format | BPP | Supported | Description |
|
||||||
|
| | | by offline | |
|
||||||
|
| | | converter | |
|
||||||
|
+==========+=====+============+=======================================+
|
||||||
|
| A1 | 1 | No | Like A8 but only 255 alpha or 0 alpha |
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
| A2 | 2 | No | Like A8 but 4 alpha values |
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
| A4 | 4 | No | Like A8 but 16 alpha values |
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
| ARGB2222 | 8 | No | ARGB2222 |
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
| ARGB1555 | 16 | No | ARGB1555 |
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
| ARGB4444 | 16 | No | ARGB4444 |
|
||||||
|
+----------+-----+------------+---------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
YUV Planar Formats
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Reference: https://wiki.videolan.org/YUV/
|
||||||
|
|
||||||
|
.. container:: tighter-table-3
|
||||||
|
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
| Format | BPP | Supported | Description |
|
||||||
|
| | | by offline | |
|
||||||
|
| | | converter | |
|
||||||
|
+========+=====+============+===================================================+
|
||||||
|
| I420 | | No | YUV420 planar (3 plane) |
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
| I422 | | No | YUV422 planar (3 plane) |
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
| I444 | | No | YUV444 planar (3 plane) |
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
| I400 | | No | YUV400 no chroma channel |
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
| NV21 | | No | YUV420 planar (2 plane), UV plane in 'V, U, V, U' |
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
| NV12 | | No | YUV420 planar (2 plane), UV plane in 'U, V, U, V' |
|
||||||
|
+--------+-----+------------+---------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
YUV Packed Formats
|
||||||
|
------------------
|
||||||
|
|
||||||
|
+--------+-----+------------+------------------------------+
|
||||||
|
| Format | BPP | Supported | Description |
|
||||||
|
| | | by offline | |
|
||||||
|
| | | converter | |
|
||||||
|
+========+=====+============+==============================+
|
||||||
|
| YUY2 | | No | YUV422 packed like 'Y U Y V' |
|
||||||
|
+--------+-----+------------+------------------------------+
|
||||||
|
| UYVY | | No | YUV422 packed like 'U Y V Y' |
|
||||||
|
+--------+-----+------------+------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
Proprietary Formats
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
| Format | BPP | Supported | Description |
|
||||||
|
| | | by offline | |
|
||||||
|
| | | converter | |
|
||||||
|
+=============+=====+============+=============+
|
||||||
|
| NEMA_TSC4 | | No | NEMA TSC4 |
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
| NEMA_TSC6 | | No | NEMA TSC6 |
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
| NEMA_TSC6A | | No | NEMA TSC6A |
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
| NEMA_TSC6AP | | No | NEMA TSC6AP |
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
| NEMA_TSC12 | | No | NEMA TSC12 |
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
| NEMA_TSC12A | | No | NEMA TSC12A |
|
||||||
|
+-------------+-----+------------+-------------+
|
||||||
|
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
.. _image_decoders:
|
||||||
|
|
||||||
|
==============
|
||||||
|
Image Decoders
|
||||||
|
==============
|
||||||
|
|
||||||
|
What is an Image Decoder?
|
||||||
|
*************************
|
||||||
|
|
||||||
|
Images that are encoded (i.e. outside of the list of built-in supported
|
||||||
|
:ref:`images_color_formats`) are dealt with through an Image Decoder. An Image
|
||||||
|
Decoder is a body of logic that can convert a coded image into one of the
|
||||||
|
recognized formats.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _built-in image decoders:
|
||||||
|
|
||||||
|
Built-In Image Decoders
|
||||||
|
***********************
|
||||||
|
|
||||||
|
LVGL comes with a number of image decoders to support a number of popular image formats:
|
||||||
|
|
||||||
|
.. container:: tighter-table-5
|
||||||
|
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| Format | ``lv_conf.h`` | Reference | External | Form | RAM Cost |
|
||||||
|
| | Symbol to Set | | Library | | |
|
||||||
|
| | | | Required? | | |
|
||||||
|
+=========+======================+====================+===========+=======================+=====================+
|
||||||
|
| BMP | LV_USE_BMP | :ref:`bmp` | No | File only | Low (1 draw buffer) |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| PNG | LV_USE_LODEPNG | :ref:`lodepng_rst` | No | File or variable | Full image |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| PNG | LV_USE_LIBPNG | :ref:`libpng` | Yes | File or variable | Full image |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| JPG | LV_USE_LIBJPEG_TURBO | :ref:`libjpeg` | Yes | File only | 8x8 Pixel Tiles |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| JPG | LV_USE_TJPGD | :ref:`tjpgd` | Yes | File or variable | 8x8 Pixel Tiles |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| WEBP | LV_USE_LIBWEBP | :ref:`libwebp` | Yes | File only | Full image |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| SVG | LV_USE_SVG | :ref:`svg` | No | File or variable | Full image |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| GIF | LV_USE_GIF | :ref:`gif` | No | Use GIF Widget (File) | Widget + 1 frame |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
| Lottie | See reference | :ref:`lv_lottie` | No | Use Lottie Widget | Widget + 1 frame |
|
||||||
|
+---------+----------------------+--------------------+-----------+-----------------------+---------------------+
|
||||||
|
|
||||||
|
Once you have the appropriate symbol set to ``1`` in ``lv_conf.h``, to use a file,
|
||||||
|
simply make the file accessible on an external storage device. You will need to then
|
||||||
|
pass the :ref:`file-system <file_system>` path to the file containing your image as
|
||||||
|
the ``src`` argument to :cpp:expr:`lv_image_set_src(icon, "S:my_icon.png")`, and LVGL
|
||||||
|
takes care of the rest.
|
||||||
|
|
||||||
|
To use the encoded file as a variable, choose one of these approaches:
|
||||||
|
|
||||||
|
- Use the online- or offline converter to convert the file to an
|
||||||
|
:cpp:type:`lv_image_dsc_t` object + data into a ``.c`` file and compile and link it
|
||||||
|
into your project. The color format is stored in the ``header.cf`` field of the
|
||||||
|
:cpp:type:`lv_image_dsc_t` struct.
|
||||||
|
|
||||||
|
- There could be case where it was needed to load an image file into
|
||||||
|
dynamically-allocated RAM at run-time and free it later, thus avoiding storing the
|
||||||
|
images as part of the application. In this case, you could manually create a
|
||||||
|
:cpp:type:`lv_image_dsc_t` and point the ``data`` field to the byte array containing
|
||||||
|
the file content and set the ``header.cf`` field to :c:macro:`LV_COLOR_FORMAT_RAW`
|
||||||
|
or :c:macro:`LV_COLOR_FORMAT_RAW_ALPHA`, and set the image source to this
|
||||||
|
:cpp:type:`lv_image_dsc_t` object using :cpp:expr:`lv_image_set_src(icon, &my_img_dsc)`,
|
||||||
|
and when it is time to decode, the registered decoder that recognizes the image
|
||||||
|
format will be used to decode it.
|
||||||
|
|
||||||
|
The types having the word "variable" in the "Form" column in the table above would
|
||||||
|
support this approach if it was needed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using Custom Image Formats
|
||||||
|
**************************
|
||||||
|
|
||||||
|
If you have a file-based image type that is not in the above list, you can set up LVGL
|
||||||
|
to successfully handle it by implementing a custom image decoder. You can use an
|
||||||
|
external decoding library or write your own. To "connect" it to LVGL, use
|
||||||
|
LVGL's *Image Decoder* interface.
|
||||||
|
|
||||||
|
An image decoder consists of 4 callbacks:
|
||||||
|
|
||||||
|
:info: Get some basic info about the image (width, height and color format).
|
||||||
|
:open: Open an image:
|
||||||
|
|
||||||
|
- optionally store entire decoded image;
|
||||||
|
- set ``dsc->decoded`` to ``NULL`` to indicate the image can be decoded incrementally;
|
||||||
|
- return :cpp:enumerator:`LV_RESULT_OK` if decoder can decode the given
|
||||||
|
image, :cpp:enumerator:`LV_RESULT_INVALID` otherwise. (This is normally
|
||||||
|
done by reading the image header from the file and determining
|
||||||
|
compatibility by reading the header content.)
|
||||||
|
|
||||||
|
:get_area: If *open* didn't fully open an image this function should decode the
|
||||||
|
indicated area of the image into the draw buffer.
|
||||||
|
:close: Close an opened image, and free the allocated resources.
|
||||||
|
|
||||||
|
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 built-in decoder understands all the formats in :ref:`images_color_formats` minus
|
||||||
|
the ``RAW`` formats.
|
||||||
|
|
||||||
|
|
||||||
|
.. _custom_image_formats:
|
||||||
|
|
||||||
|
Custom Image Formats
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The easiest way to create a custom image is to use the online image converter and
|
||||||
|
select ``RAW`` or ``RAW_WITH_ALPHA`` format. It will just take every byte of the
|
||||||
|
binary file you uploaded and write it as an image "bitmap". You then need to attach
|
||||||
|
an image decoder that will parse that bitmap and generate the real, render-able
|
||||||
|
bitmap.
|
||||||
|
|
||||||
|
``header.cf`` will be :cpp:enumerator:`LV_COLOR_FORMAT_RAW`,
|
||||||
|
:cpp:enumerator:`LV_COLOR_FORMAT_RAW_ALPHA` accordingly. Use the format according
|
||||||
|
to your needs: a fully opaque image, or one using an alpha channel.
|
||||||
|
|
||||||
|
The decoded format of a RAW image depends on the decoder. Example: JPG images are
|
||||||
|
decoded to RGB888 and PNG images are decoded to ARGB8888. See
|
||||||
|
:ref:`images_color_formats` for more details.
|
||||||
|
|
||||||
|
|
||||||
|
Registering an Image Decoder
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Here's an example of getting LVGL to work with a custom format using the PNG decoder
|
||||||
|
as an example. In ``lv_libpng.c``, see the following functions as examples to follow.
|
||||||
|
|
||||||
|
.. container:: tighter-table-1
|
||||||
|
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
| Action | Function |
|
||||||
|
+==============================================+=========================+
|
||||||
|
| Create and register image decoder | lv_libpng_init() |
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
| De-initialize image decoder | lv_libpng_deinit() |
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
| Gather basic information about the image | decoder_info() |
|
||||||
|
| and store it in ``header``. | |
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
| Open a image and generate decoded image [1]_ | decoder_open() |
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
| Free any allocated resources | decoder_close() |
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
| Partially decode based on specified area | decoder_get_area() [2]_ |
|
||||||
|
| (Optional: use if ``decoder_open()`` does | |
|
||||||
|
| not decode whole image.) | |
|
||||||
|
+----------------------------------------------+-------------------------+
|
||||||
|
|
||||||
|
.. [1]
|
||||||
|
|
||||||
|
In ``decoder_open()``, you should try to open the image source pointed by
|
||||||
|
``dsc->src``. Its type is already in ``dsc->src_type == LV_IMG_SRC_FILE/VARIABLE``.
|
||||||
|
If this format/type is not supported by the decoder, return :cpp:enumerator:`LV_RESULT_INVALID`.
|
||||||
|
However, if you can open the image, a pointer to the decoded image should be
|
||||||
|
set in ``dsc->decoded``. If the format is known, but you don't want to
|
||||||
|
decode the entire image (e.g. no memory for it), set ``dsc->decoded = NULL`` and
|
||||||
|
use ``decoder_get_area()`` to get the image area pixels.
|
||||||
|
|
||||||
|
.. [2]
|
||||||
|
|
||||||
|
``lv_bmp.c`` has an example of ``decoder_get_area()``.
|
||||||
|
|
||||||
|
|
||||||
|
Manually Using an Image Decoder
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
LVGL will use registered image decoders automatically if you try and
|
||||||
|
draw a raw image (i.e. using the ``lv_image`` Widget) but you can use them
|
||||||
|
manually as well. Create an :cpp:type:`lv_image_decoder_dsc_t` variable to describe
|
||||||
|
the decoding session and call :cpp:func:`lv_image_decoder_open`.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_result_t res;
|
||||||
|
lv_image_decoder_dsc_t dsc;
|
||||||
|
lv_image_decoder_args_t args = { 0 }; /* Custom decoder behavior via args */
|
||||||
|
res = lv_image_decoder_open(&dsc, &my_img_dsc, &args);
|
||||||
|
|
||||||
|
if(res == LV_RESULT_OK) {
|
||||||
|
/* Do something with `dsc->decoded`. You can copy out the decoded image by `lv_draw_buf_dup(dsc.decoded)`*/
|
||||||
|
lv_image_decoder_close(&dsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You would need to set :c:macro:`LV_USE_PRIVATE_API` to ``1`` in ``lv_conf.h``
|
||||||
|
in order to do this since the definition of the :cpp:type:`lv_image_decoder_dsc_t`
|
||||||
|
and :cpp:type:`_lv_image_decoder_args_t` structs are both in a private header file.
|
||||||
|
|
||||||
|
|
||||||
|
Image Post-Processing
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Considering that some hardware has special requirements for image formats, such as
|
||||||
|
alpha premultiplication and stride alignment, most image decoders (such as PNG
|
||||||
|
decoders) may not directly output image data that meets hardware requirements.
|
||||||
|
|
||||||
|
For this reason, LVGL provides a method for implementing custom image post-processing
|
||||||
|
to address unpredicted future GPU requirements (over and above the premultiplication
|
||||||
|
and stride alignment provided by :cpp:func:`lv_image_decoder_post_process`):
|
||||||
|
|
||||||
|
- In your custom GPU :ref:`draw unit <draw units>`, call a custom post-processing
|
||||||
|
function after ``lv_image_decoder_open`` to adjust the data in the image cache, and
|
||||||
|
- then mark the processing status in ``cache_entry->process_state`` (to avoid repeated
|
||||||
|
post-processing).
|
||||||
|
|
||||||
|
The below code example assumes the image was opened using the decoder interface
|
||||||
|
(e.g. using :ref:`libpng` and thus has already called
|
||||||
|
:cpp:func:`lv_image_decoder_post_process` to perform stride alignment and/or
|
||||||
|
premultiplication via the decoder descriptor's ``args`` field).
|
||||||
|
|
||||||
|
Example (requires :c:macro:`LV_USE_PRIVATE_API` to ``1`` in ``lv_conf.h``):
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
/* Define post-processing state */
|
||||||
|
typedef enum {
|
||||||
|
MY_IMAGE_PROCESS_STATE_NONE = 0,
|
||||||
|
MY_IMAGE_PROCESS_STATE_BIT_SHIFTED = 1 << 4,
|
||||||
|
} image_process_state_t;
|
||||||
|
|
||||||
|
lv_result_t my_image_post_process(lv_image_decoder_dsc_t * dsc)
|
||||||
|
{
|
||||||
|
lv_color_format_t color_format = dsc->header.cf;
|
||||||
|
lv_result_t res = LV_RESULT_OK;
|
||||||
|
|
||||||
|
if (color_format == LV_COLOR_FORMAT_ARGB8888) {
|
||||||
|
lv_cache_t * cache_p = dsc->cache;
|
||||||
|
lv_cache_entry_t * entry = dsc->cache_entry;
|
||||||
|
lv_mutex_lock(&cache_p->lock);
|
||||||
|
|
||||||
|
if (!(entry->flags & MY_IMAGE_PROCESS_STATE_BIT_SHIFTED)) {
|
||||||
|
lv_draw_buf_t * shifted_buf = NULL; /* Insert allocation call here. */
|
||||||
|
if (shifted_buf == NULL) {
|
||||||
|
LV_LOG_ERROR("No memory for bit-shifting adjustment.");
|
||||||
|
res = LV_RESULT_INVALID;
|
||||||
|
goto alloc_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle additional GPU requirement here. */
|
||||||
|
|
||||||
|
lv_free(dsc->decoded);
|
||||||
|
dsc->decoded = shifted_buf;
|
||||||
|
entry->flags |= MY_IMAGE_PROCESS_STATE_BIT_SHIFTED;
|
||||||
|
LV_LOG_USER("Bit shifting completed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc_failed:
|
||||||
|
lv_mutex_unlock(&cache_p->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GPU draw unit */
|
||||||
|
|
||||||
|
void gpu_draw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords)
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
lv_image_decoder_dsc_t decoder_dsc;
|
||||||
|
lv_image_decoder_args_t args;
|
||||||
|
lv_memzero(&args, sizeof(args));
|
||||||
|
args.premultiply = true;
|
||||||
|
args.stride_align = true;
|
||||||
|
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, &args);
|
||||||
|
|
||||||
|
if (res != LV_RESULT_OK) {
|
||||||
|
LV_LOG_ERROR("Failed to open image");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pre-multiplication and stride alignment are now done from the call to
|
||||||
|
* lv_image_decoder_open() above. But our additional GPU requirement (which we
|
||||||
|
* are calling bit-shifting above) isn't handled yet, so we do it below. */
|
||||||
|
res = my_image_post_process(&decoder_dsc);
|
||||||
|
if (res != LV_RESULT_OK) {
|
||||||
|
LV_LOG_ERROR("Failed to post-process image");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
***
|
||||||
|
|
||||||
|
.. API equals: lv_image_decoder_open
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
.. _images:
|
||||||
|
|
||||||
|
======
|
||||||
|
Images
|
||||||
|
======
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
overview
|
||||||
|
sources
|
||||||
|
color_formats
|
||||||
|
adding_images
|
||||||
|
using_images
|
||||||
|
decoders
|
||||||
|
caching
|
||||||
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
.. _images overview:
|
||||||
|
|
||||||
|
========
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
In LVGL, the term "image" can refer to two things:
|
||||||
|
|
||||||
|
- an :ref:`lv_image` Widget (capitalized), or
|
||||||
|
- data that is used to draw an image to a Display.
|
||||||
|
|
||||||
|
This section of LVGL documentation is about the latter: it describes how to use the
|
||||||
|
LVGL images module to draw images (in various forms) to a Display.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
What is an Image?
|
||||||
|
*****************
|
||||||
|
|
||||||
|
An image can be thought of as set of pixels used to create an image on a Display.
|
||||||
|
Images can be:
|
||||||
|
|
||||||
|
- an :cpp:type:`lv_image_dsc_t` object plus its pixel data in RAM or ROM in any of the
|
||||||
|
:ref:`supported pixel formats <images_color_formats>`, or
|
||||||
|
|
||||||
|
- a stored image in a file on an external file system, or loaded into RAM or ROM.
|
||||||
|
Such files can contain color formats other than the supported formats (e.g. JPEG,
|
||||||
|
BMP, PNG, SVG, WEBP, GIF or other formats).
|
||||||
|
|
||||||
|
When the color format of the image is not in the same format as the :ref:`Display <display>` it
|
||||||
|
will be sent to, the drawing logic converts those pixels to the target Display's
|
||||||
|
format (into a buffer) when it is drawn.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using Images
|
||||||
|
************
|
||||||
|
|
||||||
|
You make use of images by using any of these Widgets:
|
||||||
|
|
||||||
|
+-----------------------+---------------------------------+
|
||||||
|
| Widget | Via |
|
||||||
|
+=======================+=================================+
|
||||||
|
| :ref:`lv_image` | setting image source |
|
||||||
|
+-----------------------+---------------------------------+
|
||||||
|
| :ref:`lv_imagebutton` | setting image source |
|
||||||
|
+-----------------------+---------------------------------+
|
||||||
|
| :ref:`lv_animimg` | setting image source |
|
||||||
|
+-----------------------+---------------------------------+
|
||||||
|
| :ref:`lv_canvas` | direct access to drawing buffer |
|
||||||
|
+-----------------------+---------------------------------+
|
||||||
|
| any | background image style |
|
||||||
|
+-----------------------+---------------------------------+
|
||||||
|
|
||||||
|
There are also a number of Widgets that use Image Widgets internally for optional icons:
|
||||||
|
|
||||||
|
- :ref:`lv_list`
|
||||||
|
- :ref:`lv_menu`
|
||||||
|
- :ref:`lv_msgbox`
|
||||||
|
- :ref:`lv_win`
|
||||||
|
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
.. include:: /include/external_links.txt
|
||||||
|
|
||||||
|
.. _image_sources:
|
||||||
|
|
||||||
|
=============
|
||||||
|
Image Sources
|
||||||
|
=============
|
||||||
|
|
||||||
|
The images module supports images in any of 3 forms:
|
||||||
|
|
||||||
|
.. container:: tighter-table-3
|
||||||
|
|
||||||
|
+------------+------------------------------------------------------------------+
|
||||||
|
| Form | Source |
|
||||||
|
+============+==================================================================+
|
||||||
|
| Variables_ | :cpp:type:`lv_image_dsc_t` object + data in ROM or RAM |
|
||||||
|
+------------+------------------------------------------------------------------+
|
||||||
|
| Files_ | :ref:`file_system` path to file (e.g. JPG, PNG, BMP etc.) |
|
||||||
|
+------------+------------------------------------------------------------------+
|
||||||
|
| Symbols_ | C strings starting with Unicode characters (e.g. icons) in UTF-8 |
|
||||||
|
+------------+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Image sources are set by calling one of the ``..._set_src()`` functions. See code
|
||||||
|
examples below.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _image_sources_variables:
|
||||||
|
|
||||||
|
Variables
|
||||||
|
*********
|
||||||
|
|
||||||
|
In this context, a "variable" is a C symbol that is used in C code to refer to an
|
||||||
|
object in either RAM or ROM.
|
||||||
|
|
||||||
|
Images stored as variables are comprised of an :cpp:struct:`lv_image_dsc_t` struct
|
||||||
|
plus its data. The struct contains the following fields:
|
||||||
|
|
||||||
|
:header:
|
||||||
|
|
||||||
|
:magic: Magic number (must be LV_IMAGE_HEADER_MAGIC)
|
||||||
|
:cf: Color format. See :ref:`images_color_formats`.
|
||||||
|
:flags: Image flags (any of the ``LV_IMAGE_FLAGS_...`` enumeration values).
|
||||||
|
:w: Width in pixels (<= 2048)
|
||||||
|
:h: Height in pixels (<= 2048)
|
||||||
|
:stride: Number of bytes between the beginning of one row of pixels and the beginning of the next row
|
||||||
|
:reserved_2: reserved for future use
|
||||||
|
|
||||||
|
:data_size: length of ``data`` in bytes
|
||||||
|
:data: pointer to a byte array where the data of the image is stored (pixels
|
||||||
|
and sometimes indexed color palettes [for indexed color formats]).
|
||||||
|
When ``header.cf`` is one of the ``RAW`` formats, this can also contain
|
||||||
|
the contents of a file loaded into RAM at run-time, or embedded in ROM
|
||||||
|
(program space).
|
||||||
|
|
||||||
|
|
||||||
|
These are usually stored within a project as a C file generated by one of these two
|
||||||
|
LVGL image converters:
|
||||||
|
|
||||||
|
- `LVGL Online Image Converter`_
|
||||||
|
- Offline converter in ``./scripts/LVGLImage.py``.
|
||||||
|
|
||||||
|
At this writing, the online converter supports these formats:
|
||||||
|
|
||||||
|
- RGB565
|
||||||
|
- RGB565A8
|
||||||
|
- RGB888
|
||||||
|
- XRGB8888
|
||||||
|
- ARGB8888
|
||||||
|
|
||||||
|
The offline converter can convert an image into the above formats plus all the other
|
||||||
|
supported color formats.
|
||||||
|
|
||||||
|
The generated C files are compiled and linked into the resulting executable like any
|
||||||
|
other ``const`` data.
|
||||||
|
|
||||||
|
See :ref:`adding images to your project` for more details.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
LV_IMAGE_DECLARE(img_cogwheel_argb);
|
||||||
|
lv_obj_t * img = lv_image_create(lv_screen_active());
|
||||||
|
lv_image_set_src(img, &img_cogwheel_argb);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _image_sources_files:
|
||||||
|
|
||||||
|
Files
|
||||||
|
*****
|
||||||
|
|
||||||
|
Files can be used as image sources by passing in the path string to the image file
|
||||||
|
to the ``lv_<widget>_set_src()`` function as the ``src`` argument. The string must
|
||||||
|
begin with a printable ASCII character (range [0x20-0x7F]). Example:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_image_set_src(icon, "S:my_icon.png");
|
||||||
|
|
||||||
|
Images stored as files are normally 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.
|
||||||
|
|
||||||
|
Exceptions where there is no meaningful extra memory usage:
|
||||||
|
|
||||||
|
- JPEG: Only a few pixels are read and drawn at once.
|
||||||
|
- BMP: Pixels are transferred directly from the file to the draw buffer.
|
||||||
|
- BIN: Pixels are transferred line-by-line to the draw buffer.
|
||||||
|
|
||||||
|
For the images module to deal with files you need to add a *Driver* for the target
|
||||||
|
storage system to LVGL. See :ref:`file_system` for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _image_sources_symbols:
|
||||||
|
|
||||||
|
Symbols
|
||||||
|
*******
|
||||||
|
|
||||||
|
Symbols that can be used as an image source are ``char *`` strings beginning with a
|
||||||
|
Unicode character encoded in UTF-8, which will have a first-byte value >= 0x80. After
|
||||||
|
that, these strings can contain any other characters, including additional Unicode
|
||||||
|
characters. Such strings are passed as the image source like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_image_set_src(icon, LV_SYMBOL_BATTERY_FULL);
|
||||||
|
/* or */
|
||||||
|
lv_image_set_src(icon, LV_SYMBOL_OK " Accept");
|
||||||
|
|
||||||
|
The file ``./src/font/lv_symbol_def.h`` contains a wide variety of Unicode symbols you
|
||||||
|
can use directly, or you can make your own. See :ref:`font_adding_a_custom_symbol`
|
||||||
|
for details.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Symbols are only implemented for :ref:`lv_image` Widgets.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
********
|
||||||
|
|
||||||
|
See :ref:`Using Images Examples <using_images_examples>` for a number of examples of
|
||||||
|
using image sources in these 3 forms.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
***
|
||||||
|
|
||||||
|
.. API equals: lv_image_set_src
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
.. _using images:
|
||||||
|
|
||||||
|
============
|
||||||
|
Using Images
|
||||||
|
============
|
||||||
|
|
||||||
|
The simplest way to use an image in LVGL is to display it with an
|
||||||
|
:ref:`lv_image` Widget:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_obj_t * icon = lv_image_create(lv_screen_active());
|
||||||
|
|
||||||
|
/* From variable */
|
||||||
|
lv_image_set_src(icon, &my_img_dsc);
|
||||||
|
|
||||||
|
/* From file */
|
||||||
|
lv_image_set_src(icon, "S:my_icon.bin");
|
||||||
|
|
||||||
|
/* From Unicode string */
|
||||||
|
lv_image_set_src(icon, LV_SYMBOL_BATTERY_FULL);
|
||||||
|
|
||||||
|
If the image was converted to a variable with the :ref:`online <images_online_converter>`
|
||||||
|
or :ref:`offline converter <images_offline_converter>`, you should use
|
||||||
|
:cpp:expr:`LV_IMAGE_DECLARE(my_img_dsc)` to declare the image in the file where
|
||||||
|
you want to use it.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _using_images_examples:
|
||||||
|
|
||||||
|
Examples
|
||||||
|
********
|
||||||
|
|
||||||
|
.. include:: /examples/widgets/image/index.rst
|
||||||
|
|
||||||
|
.. include:: /examples/libs/bmp/index.rst
|
||||||
|
|
||||||
|
.. include:: /examples/libs/libpng/index.rst
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ Main Modules
|
|||||||
display/index
|
display/index
|
||||||
indev/index
|
indev/index
|
||||||
fonts/index
|
fonts/index
|
||||||
image
|
images/index
|
||||||
color
|
color
|
||||||
timer
|
timer
|
||||||
animation
|
animation
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Or you can use
|
|||||||
|
|
||||||
Canvas supports all the color formats like
|
Canvas supports all the color formats like
|
||||||
:cpp:enumerator:`LV_COLOR_FORMAT_ARGB8888` or :cpp:enumerator:`LV_COLOR_FORMAT_I2`. See the full
|
:cpp:enumerator:`LV_COLOR_FORMAT_ARGB8888` or :cpp:enumerator:`LV_COLOR_FORMAT_I2`. See the full
|
||||||
list in the :ref:`Color formats <overview_image_color_formats>` section.
|
list in the :ref:`Color formats <images_color_formats>` section.
|
||||||
|
|
||||||
Indexed colors
|
Indexed colors
|
||||||
--------------
|
--------------
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
.. include:: /include/substitutions.txt
|
.. include:: /include/substitutions.txt
|
||||||
|
.. include:: /include/external_links.txt
|
||||||
.. _lv_image:
|
.. _lv_image:
|
||||||
|
|
||||||
================
|
================
|
||||||
@@ -11,7 +12,7 @@ Overview
|
|||||||
Images are Widgets that display images from flash (as arrays) or
|
Images are Widgets that display images from flash (as arrays) or
|
||||||
from files. Images can also display symbols (``LV_SYMBOL_...``).
|
from files. Images can also display symbols (``LV_SYMBOL_...``).
|
||||||
|
|
||||||
Using the :ref:`Image decoder interface <overview_image_decoder>`, custom image formats
|
Using the :ref:`Image decoder interface <image_decoders>`, custom image formats
|
||||||
can be supported as well.
|
can be supported as well.
|
||||||
|
|
||||||
.. _lv_image_parts_and_styles:
|
.. _lv_image_parts_and_styles:
|
||||||
@@ -39,7 +40,7 @@ To provide maximum flexibility, the source of the image can be:
|
|||||||
|
|
||||||
To set the source of an image, use :cpp:expr:`lv_image_set_src(img, src)`.
|
To set the source of an image, use :cpp:expr:`lv_image_set_src(img, src)`.
|
||||||
|
|
||||||
To generate a pixel array from a PNG, JPG or BMP image, use the `Online image converter tool <https://lvgl.io/tools/imageconverter>`__
|
To generate a pixel array from a PNG, JPG or BMP image, use the `LVGL Online Image Converter`_
|
||||||
and set the converted image as the image source with its pointer with
|
and set the converted image as the image source with its pointer with
|
||||||
:cpp:expr:`lv_image_set_src(img1, &converted_img_var)`.
|
:cpp:expr:`lv_image_set_src(img1, &converted_img_var)`.
|
||||||
To make the converted image variable accessible from the C file, declare it with
|
To make the converted image variable accessible from the C file, declare it with
|
||||||
@@ -88,8 +89,8 @@ Besides RGB888 and ARGB8888 color formats, the following formats are supported:
|
|||||||
- **Indexed**: Image has a color palette, and each pixel is an index into that palette.
|
- **Indexed**: Image has a color palette, and each pixel is an index into that palette.
|
||||||
- **Alpha indexed**: The values stored at pixel positions are alpha (opacity) values.
|
- **Alpha indexed**: The values stored at pixel positions are alpha (opacity) values.
|
||||||
|
|
||||||
These options can be selected in the image converter. Learn more
|
These options can be selected in the `LVGL Online Image Converter`_. Learn more
|
||||||
about color formats in the :ref:`overview_image_color_formats` section.
|
about color formats in the :ref:`images_color_formats` section.
|
||||||
|
|
||||||
Recolor
|
Recolor
|
||||||
-------
|
-------
|
||||||
@@ -141,7 +142,7 @@ causes the transformations to be of higher quality, but slower.
|
|||||||
Transformations require the whole image to be available. Therefore
|
Transformations require the whole image to be available. Therefore
|
||||||
indexed images (``LV_COLOR_FORMAT_I1/2/4/8_...``) and alpha only images cannot be transformed.
|
indexed images (``LV_COLOR_FORMAT_I1/2/4/8_...``) and alpha only images cannot be transformed.
|
||||||
In other words transformations work only on normal (A)RGB or A8 images stored as a
|
In other words transformations work only on normal (A)RGB or A8 images stored as a
|
||||||
C array, or on images provided by a custom :ref:`overview_image_decoder`
|
C array, or on images provided by a custom :ref:`image_decoders`
|
||||||
that returns the whole image.
|
that returns the whole image.
|
||||||
|
|
||||||
Note that the real coordinates of image Widgets do not change with a
|
Note that the real coordinates of image Widgets do not change with a
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
.. _VSCode Simulator: https://github.com/lvgl/lv_port_pc_vscode
|
.. _VSCode Simulator: https://github.com/lvgl/lv_port_pc_vscode
|
||||||
.. _Figma: https://www.figma.com/
|
.. _Figma: https://www.figma.com/
|
||||||
.. _see all plans: https://pro.lvgl.io/pricing
|
.. _see all plans: https://pro.lvgl.io/pricing
|
||||||
|
.. _LVGL Online Image Converter: https://lvgl.io/tools/imageconverter
|
||||||
|
.. _LVGL Online Font Converter: https://lvgl.io/tools/fontconverter
|
||||||
|
|||||||
Reference in New Issue
Block a user