跳转到主要内容

使用L8图像格式减少存储空间消耗

L8格式的图像占用的闪存空间较少,比诸如ARGB8888等格式的绘制速度更快。

L8格式的图像包含调色板和像素数组:调色板包含了指定的至多256种颜色,可以为16位RGB565格式、24位RGB888格式或32位ARGB8888格式。 像素数组包含每个像素一个字节的数据。 该字节数据是调色板(颜色列表)索引,指向像素的颜色。 为了绘制L8图像,TouchGFX框架逐一读取像素,在调色板中查找颜色,再将其写入帧缓冲。 这些操作是自动完成的,如果硬件支持,可以通过STM32 Chrom-ART硬件加速器进行加速。

每像素8位意味着一幅L8图像可使用256种不同颜色。 另一幅L8图像可使用256种其他颜色,这是因为两幅图像各有自己的调色板。

一幅有4 x 4个像素的L8图像和一个包含4种颜色的调色板

每个像素一个字节(8位)。 因此,像素数据大小等于(宽度 x 高度)个字节。 调色板颜色可以是16位、24位或32位颜色。 因此,每种颜色定义将占用2、3或4个字节。

立体图像应存储在L8_RGB888中。 如果图像是透明的,则必须使用32位格式(ARGB8888):

格式帧缓冲格式支持透明像素 DMA2D支持
L8_RGB56516位RGB565
L8_RGB88824位RGB888
L8_ARGB8888二者兼有

DMA2D不支持带RGB565调色板的L8格式。 这意味着绘制这种格式的图像不会执行硬件加速。 因此,除非您使用的平台没有DMA2D(例如:STM32G0或STM32F410),否则不应使用这种格式。

如果您使用了一个串行Flash(非存储映射)来存储图像,并使用了一个16位帧缓存(格式为RGB565),那么您应该使用L8_RGB565格式,因为色彩格式与帧缓存格式匹配,且复制到帧缓存会更快。

下表显示了首选的L8格式:

帧缓冲格式有DMA2D的平台 无DMA2D的平台
RGB565L8_RGB888L8_RGB565
RGB888L8_RGB888L8_RGB888
ARGB8888L8_RGB888L8_RGB888

透明图像应始终使用L8_ARGB8888格式。

Further reading
  • 点击链接阅读关于调色板图像格式的更多内容:https://en.wikipedia.org/wiki/Indexed_color
  • L8 Image

    这是一幅典型的徽标图像。 这幅图像只使用了16种不同颜色:

    200 x 200像素L8图像,有16种24位颜色。

    此图像占用的闪存空间明显小于标准24位格式(RGB888)的原始图像。 下表列出了此实际图像使用三种不同调色板格式和非L8格式的闪存占用量。

    格式像素大小(字节)调色板大小(字节)总大小(字节)Reduction (%)
    RGB888120,0000120,000-
    L8_RGB56540,0003240,03266.6
    L8_RGB88840,0004840,04866.6
    L8_ARGB888840,0006440,06466.6

    我们看到图像大小缩减率很大,调色板的大小在中等尺寸图像上显得微不足道。

    在TouchGFX Designer中使用L8图像

    TouchGFX中L8图像格式的使用十分简单。 The only thing to do is to configure the Image Converter to convert the image from PNG to L8 format. 下面我们将介绍整个过程:

    在TouchGFX Designer中启动一个新工程。 将图像复制到新工程中的assets/images文件夹:

    TouchGFX工程的Images文件夹

    现在转至TouchGFX Designer,点击顶部导航栏中的“图像”选项卡并选中图像:

    进入TouchGFX Designer的图像视图

    在窗口右侧,选择图像格式L8_RGB888(本例运行24位颜色)。

    现在,可以在画布上插入一个图像控件(这里我们在背景上插入了一个方框):

    TouchGFX Designer中画布上的图像控件

    无需在UI代码中做任何修改。 根据我们在“图像”选项卡上所做设置,图像转换器转换PNG文件并生成L8格式的图像。

    透明图像

    如前面所述,还可以对透明图像使用L8图像。

    32位ARGB8888格式的170 x 60像素按钮图像

    以上图像使用了108种颜色(许多色度的蓝色)。 此图像可使用格式L8_ARGB8888。 大小将显著缩减:

    格式像素大小(字节)调色板大小(字节)总大小(字节)缩减率%
    ARGB888840,800040,800-
    L8_ARGB888810,20043210,63273.9%

    L8 Image Compression

    Memory consumption can be reduced even more by selecting L8 compression of your L8 image. The Image Converter supports 3 compression algorithms (L4, RLE, LZW9). In the TouchGFX Designer you can set the Compression value to "Auto", this will let the Image Converter select the suitable algorithm for your image, alternatively you can force a specific algorithm. The gain in reduced memory, comes in some cases with a price of increased CPU load due to decompression directly to the framebuffer when the image is drawn.

    Selecting L8 Image Compression

    Note
    Default Dither Algorithm and Alpha Dither is disabled for L8 compressed images. Select a specific Dither Algorithm and Alpha Dither on each L8 image if required.

    The L8 image compression has a default setting which is configurable on the Default Image Configuration tab in the TouchGFX Designer, see screenshot below. Here you select what the default setting for your entire application should be.

    Default L8 Image Compression setting

    Caution
    Compressed images can not be used with all Widgets. See the list.
    Further reading

    In the following we will use the L8 image from previous to demonstrate the compression capabilities of each algorithm and the performance of decompression.

    We use the STM32F429-DISCO with an application containing 4 screens, with different compressions:

    • No compression
    • L4 compression
    • RLE compression
    • LZW9 compression

    Example screen (240x320) with the L8 image running on STM32F429-DISCO

    Note
    The DMA2D is disabled to compare software rendering only.
    格式CompressionSize of pixels
    (bytes)
    Size of palette + header
    (bytes)
    Total size
    (bytes)
    Reduction
    (%)
    Performance
    (render time in ms)
    RGB565120,0000120,0000-
    L8_RGB56540,00032 + 440,03666.62.12
    L8_RGB565L420,00032 + 420,03683.32.34
    L8_RGB565RLE3,19732 + 1643,39397.21.66
    L8_RGB565LZW94,47532 + 1684.67596.17.45

    The above table shows both the memory reduction from compression and the performance for decompression when the image is drawn. Both the compression (reduction) and decompression (performance) highly relies on the complexity of the image and number of colors.
    Each algorithm has its limits of application, meaning, L4 is limited to 16 colors, RLE is limited to 64 colors and LZW9 works for all L8 images, i.e. no limits. Furthermore it is a fact that L4 and RLE performs better than LZW9, when drawing the image, but as mentioned they are not able to cover all L8 images. All algorithms will decrease in performance if the image is clipped.
    In general this means you always have to consider the number of colors (quality requirement), the flash memory available (reduction requirement) and the complexity of your application (animations) when you use L8 image compression. E.g. if you have an image with more than 64 colors and you use LZW9 but the performance penalty is to high, you could try and reduce the number of colors in the image to 64 or less, if your quality requirements allow it, and then select RLE. If that is not possible then your might be better of using an uncompressed L8 image. See ImageMagick for how to reduce colors in your image.

    If you are not going to use L8 image compression in your application, you should disable the feature, below screenshot from the TouchGFX Designer shows you how.

    Disabling L8 Image Compression

    Example of compressed and uncompressed L8 images in a Widget

    Even though L8 image compression can't be used for all widgets, it is still possible to have some images compressed and others uncompressed in a widget composed of multiple images, e.g. Gauge and Analog Clock. Below is an example showing how the background is compressed and the needle is uncompressed in a Gauge widget.

    Images used in Gauge widget

    Gauge widget

    Converting an image to 256 colors or less

    许多图像使用的颜色多于256种。 这对照片级真实感的图像或有渐变梯度的图像而言很常见。 由于这些图像包含多种颜色,因此不能在TouchGFX Designer中直接转换为L8图像格式。

    但是,在许多情况下,可以减少特定图像中使用的颜色数量。 在理想情况下,平面设计师可以转换或提供256色图像,而图像操作工具也可以执行转换,同时不会过度损失图像质量。

    Paint.NET

    最简单的办法是使用Paint.NET。 打开原始图像,使用“另存为”将图像保存为另一个文件。 在“保存设置”对话框中,选择8位像素深度:

    Paint.NET将图像保存为8位格式

    现在,在工程中使用新的PNG。 记得在TouchGFX Designer中的“图像”选项卡上选择L8_ARGB8888格式。 在许多情况下,阴影处理的不够好,但有透明边缘的图标看起来不错。 可以调整“透明度阈值”,在某些情况下可以改善效果。

    ImageMagick

    另一种合适的工具是ImageMagick(从www.imagemagick.org下载),有时也能获得更好的L8图像。 此工具可以通过命令行转换图像。 适合在脚本中用。 使用以下命令,可将clock_bg.png转换为使用至多256种颜色的图像:

    magick convert clock_bg.png -colors 256 clock_bg_l8_256.png

    You can also reduce the colors to less than 256 colors, in the case of enabling the RLE or L4 compression algorithms.

    magick convert clock_bg.png -colors 64 clock_bg_l8_64.png

    ImageMagick还可以告诉您图像中使用了多少种颜色。 使用下面命令:

    magick identify -format %k Blue_Buttons_Round_Edge_small.png

    比较

    下面比较了三幅图像(原图、使用Paint.NET的L8图像和使用ImageMagick的L8图像):

    钟表图像比较,从左到右为:原图、Paint.NET生成图,ImageMagick生成图

    中间的钟表丢失了边界阴影中的细节。 在这两种情况下,时钟背景的中央部分看起来都是可以的。

    手动配置

    It is also possible to select image formats and compression algorithm without using the TouchGFX Designer. The settings are specified in file application.config located in the project root:

    application.config
    {
    "image_configuration": {
    images": {
    "Blue_Buttons_Round_Edge_small.png": {
    "format": "L8_ARGB8888",
    "l8_compression": "LZW9"
    }
    },
    "dither_algorithm": "2",
    "alpha_dither": "yes",
    "layout_rotation": "0",
    "opaque_image_format": "RGB888",
    "nonopaque_image_format": "ARGB8888",
    "section": "ExtFlashSection",
    "extra_section": "ExtFlashSection",
    "l8_compression": "yes"
    }
    }

    “Image_configuration”下的“images”部分指定了每幅图像的格式。 在这里没有提及的图像将会以默认格式(opaque_image_format或nonopaque_image_format)生成。

    我们建议使用TouchGFX Designer进行图像设置(如可能)。