跳转到主要内容

使用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图像

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

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

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

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

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

    在TouchGFX Designer中使用L8图像

    TouchGFX中L8图像格式的使用十分简单。 只需配置图像转换器,以便将图像从PNG转换为L8格式。 下面我们将介绍整个过程:

    在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图像压缩

    通过选择L8图像压缩,可以进一步减少内存消耗。 图像转换器支持三种压缩算法(L4、RLE、LZW9)。 在TouchGFX Designer中,您可以将压缩值设置为“自动”,使图像转换器为您的图像选择合适的算法,或者您也可以强制使用特定的算法。 在某些情况下,内存减少的好处是以CPU负载增加为代价,因为在绘制图像时会直接解压缩到帧缓存。

    选择L8图像压缩

    Note
    L8压缩图像默认禁用抖动算法和阿尔法抖动。 如需要,请在每个L8图像上选择特定的抖动算法和阿尔法抖动。

    L8图像压缩有一个默认设置,可在TouchGFX Designer的默认图像配置选项卡上进行配置,请参阅以下屏幕截图。 在这里,您可以选择整个应用程序的默认设置。

    L8图像默认压缩设置

    Caution
    不是所有控件都可以使用压缩图形。 请参阅列表
    Further reading

    下文中,我们将使用之前的L8图像来演示每种算法的压缩能力和解压缩性能。

    我们将STM32F429-DISCO与包含4个屏幕的应用程序一起使用,具有不同的压缩:

    • 无压缩
    • L4压缩
    • RLE压缩
    • LZW9压缩

    STM32F429-DISCO上运行L8图像的示例屏幕(240x320)

    Note
    DMA2D被禁用,仅比较软件渲染。
    格式压缩像素大小
    (字节)
    调色板+标题的大小
    (字节)
    总大小
    (字节)
    缩减率
    (%)
    性能
    (渲染时间,毫秒)
    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

    上表显示了压缩后的内存减少情况和解压缩绘制图像性能。 压缩(缩减率)和解压缩(性能)都高度依赖于图像的复杂性和颜色的数量。
    每种算法都有其应用限制,即:L4限于16色,RLE限于64色,LZW9适用于所有L8图像,即无限制。 此外,L4和RLE在绘制图像时实际上比LZW9表现得更好,但如前所述,它们不能覆盖所有L8图像。 如果图像被压缩,所有算法都会使性能降低。
    一般来说,这意味着当您使用L8图像压缩时,必须始终考虑颜色的数量(质量要求)、可用的Flash存储器(减少要求)和应用程序(动画)的复杂性。 例如, 如果您有一个超过64种颜色的图像,并且你使用LZW9,但性能损失太大,如果质量要求允许,则可以尝试将图像中的颜色数量减少到64种或更少,然后选择RLE。 如果这不可行,那么你最好使用未压缩的L8图像。 请参阅ImageMagick了解如何减少图像中的颜色。

    如果您不打算在应用程序中使用L8图像压缩,则应禁用该功能,下面是TouchGFX 设计器的屏幕截图,展示了具体方法。

    禁用L8图像压缩

    控件中压缩和未压缩的L8图像示例

    尽管L8图像压缩不能用于所有控件,但在由多个图像组成的控件中,如:仪表和模拟时钟,仍然可以压缩某些图像,而不压缩其他图像。 下面的示例显示了在仪表控件中如何压缩背景而不压缩指针。

    仪表控件中使用的图像

    仪表控件

    将图像转换为256色或以下

    许多图像使用的颜色多于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

    在启用RLE或L4压缩算法的情况下,也可以将颜色减少到256色以下。

    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生成图

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

    手动配置

    不使用TouchGFX 设计器也可以选择图像格式和压缩算法。 指定设置的文件application.config位于项目根目录中:

    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进行图像设置(如可能)。