使用L8图像格式减少存储空间消耗
L8格式的图像占用的闪存空间较少,比诸如ARGB8888等格式的绘制速度更快。
L8格式的图像包含调色板和像素数组:调色板包含了指定的至多256种颜色,可以为16位RGB565格式、24位RGB888格式或32位ARGB8888格式。 像素数组包含每个像素一个字节的数据。 该字节数据是调色板(颜色列表)索引,指向像素的颜色。 为了绘制L8图像,TouchGFX框架逐一读取像素,在调色板中查找颜色,再将其写入帧缓冲。 这些操作是自动完成的,如果硬件支持,可以通过STM32 Chrom-ART硬件加速器进行加速。
每像素8位意味着一幅L8图像可使用256种不同颜色。 另一幅L8图像可使用256种其他颜色,这是因为两幅图像各有自己的调色板。
每个像素一个字节(8位)。 因此,像素数据大小等于(宽度 x 高度)个字节。 调色板颜色可以是16位、24位或32位颜色。 因此,每种颜色定义将占用2、3或4个字节。
立体图像应存储在L8_RGB888中。 如果图像是透明的,则必须使用32位格式(ARGB8888):
格式 | 帧缓冲格式 | 支持透明像素 | DMA2D支持 |
---|---|---|---|
L8_RGB565 | 16位RGB565 | 无 | 无 |
L8_RGB888 | 24位RGB888 | 无 | 有 |
L8_ARGB8888 | 二者兼有 | 有 | 有 |
DMA2D不支持带RGB565调色板的L8格式。 这意味着绘制这种格式的图像不会执行硬件加速。 因此,除非您使用的平台没有DMA2D(例如:STM32G0或STM32F410),否则不应使用这种格式。
如果您使用了一个串行Flash(非存储映射)来存储图像,并使用了一个16位帧缓存(格式为RGB565),那么您应该使用L8_RGB565格式,因为色彩格式与帧缓存格式匹配,且复制到帧缓存会更快。
下表显示了首选的L8格式:
帧缓冲格式 | 有DMA2D的平台 | 无DMA2D的平台 |
---|---|---|
RGB565 | L8_RGB888 | L8_RGB565 |
RGB888 | L8_RGB888 | L8_RGB888 |
ARGB8888 | L8_RGB888 | L8_RGB888 |
透明图像应始终使用L8_ARGB8888格式。
Further reading
L8图像
这是一幅典型的徽标图像。 这幅图像只使用了16种不同颜色:
此图像占用的闪存空间明显小于标准24位格式(RGB888)的原始图像。 下表列出了此实际图像使用三种不同调色板格式和非L8格式的闪存占用量。
格式 | 像素大小(字节) | 调色板大小(字节) | 总大小(字节) | 缩减率(%) |
---|---|---|---|---|
RGB888 | 120,000 | 0 | 120,000 | - |
L8_RGB565 | 40,000 | 32 | 40,032 | 66.6 |
L8_RGB888 | 40,000 | 48 | 40,048 | 66.6 |
L8_ARGB8888 | 40,000 | 64 | 40,064 | 66.6 |
我们看到图像大小缩减率很大,调色板的大小在中等尺寸图像上显得微不足道。
在TouchGFX Designer中使用L8图像
TouchGFX中L8图像格式的使用十分简单。 只需配置图像转换器,以便将图像从PNG转换为L8格式。 下面我们将介绍整个过程:
在TouchGFX Designer中启动一个新工程。 将图像复制到新工程中的assets/images文件夹:
现在转至TouchGFX Designer,点击顶部导航栏中的“图像”选项卡并选中图像:
在窗口右侧,选择图像格式L8_RGB888(本例运行24位颜色)。
现在,可以在画布上插入一个图像控件(这里我们在背景上插入了一个方框):
无需在UI代码中做任何修改。 根据我们在“图像”选项卡上所做设置,图像转换器转换PNG文件并生成L8格式的图像。
透明图像
如前面所述,还可以对透明图像使用L8图像。
以上图像使用了108种颜色(许多色度的蓝色)。 此图像可使用格式L8_ARGB8888。 大小将显著缩减:
格式 | 像素大小(字节) | 调色板大小(字节) | 总大小(字节) | 缩减率% |
---|---|---|---|---|
ARGB8888 | 40,800 | 0 | 40,800 | - |
L8_ARGB8888 | 10,200 | 432 | 10,632 | 73.9% |
将调色板移至内部Flash
在对图像使用非内存映射Flash的平台上(如:STM32G0、STM32O0或STM32C0),需要将L8调色板数据移至内部Flash。 否则,将不会绘制L8图像。
将TouchGFX设计器中的“Extra Section”更改为“IntFlashSection”,便可将图像的调色板移至内部Flash(打开“图像”选项卡,找到您的图像,然后转至最右列)。
L8图像压缩
通过选择L8图像压缩,可以进一步减少内存消耗。 图像转换器支持三种压缩算法(L4、RLE、LZW9)。 在TouchGFX Designer中,您可以将压缩值设置为“自动”,使图像转换器为您的图像选择合适的算法,或者您也可以强制使用特定的算法。 在某些情况下,内存减少的好处是以CPU负载增加为代价,因为在绘制图像时会直接解压缩到帧缓存。
Note
L8图像压缩有一个默认设置,可在TouchGFX Designer的默认图像配置选项卡上进行配置,请参阅以下屏幕截图。 在这里,您可以选择整个应用程序的默认设置。
Caution
Further reading
下文中,我们将使用之前的L8图像来演示每种算法的压缩能力和解压缩性能。
我们将STM32F429-DISCO与包含4个屏幕的应用程序一起使用,具有不同的压缩:
- 无压缩
- L4压缩
- RLE压缩
- LZW9压缩
Note
格式 | 压缩 | 像素大小 (字节) | 调色板+标题的大小 (字节) | 总大小 (字节) | 缩减率 (%) | 性能 (渲染时间,毫秒) |
---|---|---|---|---|---|---|
RGB565 | 无 | 80,000 | 0 | 80,000 | 0 | - |
L8_RGB565 | 无 | 40,000 | 32 + 4 | 40,036 | 50.0 | 2.12 |
L8_RGB565 | L4 | 20,000 | 32 + 4 | 20,036 | 75.0 | 2.34 |
L8_RGB565 | RLE | 3,197 | 32 + 164 | 3,393 | 95.7 | 1.66 |
L8_RGB565 | LZW9 | 4,475 | 32 + 168 | 4,675 | 96.1 | 7.45 |
上表显示了压缩后的内存减少情况和解压缩绘制图像性能。 压缩(减少)和解压缩(性能)都高度依赖于图像的复杂性和颜色的数量。 每种算法都有其应用限制,即:L4限于16色,RLE限于64色,LZW9适用于所有L8图像,即无限制。 此外,L4和RLE在绘制图像时实际上比LZW9表现得更好,但如前所述,它们不能覆盖所有L8图像。 如果图像被剪切,所有算法的性能都会降低。 一般来说,这意味着当您使用L8图像压缩时,必须始终考虑颜色的数量(质量要求)、可用的Flash存储器(减少要求)和应用程序(动画)的复杂性。 例如, 如果您有一个超过64种颜色的图像,并且你使用LZW9,但性能损失太大,如果质量要求允许,则可以尝试将图像中的颜色数量减少到64种或更少,然后选择RLE。 如果这不可行,那么你最好使用未压缩的L8图像。 请参阅ImageMagick了解如何减少图像中的颜色。
如果您不打算在应用程序中使用L8图像压缩,则应禁用该功能,下面是TouchGFX 设计器的屏幕截图,展示了具体方法。
控件中压缩和未压缩的L8图像示例
尽管L8图像压缩不能用于所有控件,但在由多个图像组成的控件中,如:仪表和模拟时钟,仍然可以压缩某些图像,而不压缩其他图像。 下面的示例显示了在仪表控件中如何压缩背景而不压缩指针。
将图像转换为256色或以下
许多图像使用的颜色多于256种。 这对照片级真实感的图像或有渐变梯度的图像而言很常见。 由于这些图像包含多种颜色,因此不能在TouchGFX Designer中直接转换为L8图像格式。
但是,在许多情况下,可以减少特定图像中使用的颜色数量。 在理想情况下,平面设计师可以转换或提供256色图像,而图像操作工具也可以执行转换,同时不会过度损失图像质量。
Paint.NET
最简单的办法是使用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图像):
中间的钟表丢失了边界阴影中的细节。 在这两种情况下,时钟背景的中央部分看起来都是可以的。
手动配置
不使用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进行图像设置(如可能)。