跳转到主要内容

Flash受限的GUI开发

本文介绍了如何利用TouchGFX开发低Flash存储器使用率的图形用户界面。

在使用TouchGFX生成代码时,像图像、文本和字体这样的资源会被转换成C++文件,然后在编程过程中与TouchGFX应用程序代码、用户代码和TouchGFX库一起存储在Flash存储中。 这意味着具有许多资源的大型或复杂项目会导致高Flash使用率。

由于大多数应用程序中的存储器资源都是有限的,因此有几种方法可以减少Flash存储器的使用率。 TouchGFX提供四项内置功能,可以帮助您显著减少应用程序的Flash存储器使用率。 这四项功能分别是L8图像格式、图像压缩、可缩放矢量图形(SVG)和矢量字体。

本文中,我们将了解如何利用这四项功能来限制应用程序占用的Flash存储器空间。 这些测量使用的是STM32U5G9J-DK2,但节约Flash空间的功能也可以应用于其他硬件平台。

Further reading

有关内存管理的更多信息,请阅读[内存使用] (/basic concepts/Memory Usage.mdx) 说明。

节省Flash的电动自行车演示

在TouchGFX Designer中可以找到节省Flash使用率的电动自行车演示,其中说明了如何使用TouchGFX的四项功能来节省Flash空间。 该演示是STM32U5G9J-DK2板专用演示。 具有NeoChromVG GPU是STM32U5G9J-DK2的一大优势,该硬件可以加速矢量渲染。 然而,L8图像格式和图像压缩可在所有STM32 MCU中使用。

如果演示都使用未压缩的位图(无L8、压缩、SVG和矢量字体)实现,它将占用大约10.5MB的Flash存储器。 而在采用了四项节省Flash空间的功能时,演示仅占用大约800KB的Flash存储器。 由此可以看到,大量的Flash空间被节省下来。 在演示中,四项措施总共可节约92%的Flash空间。

各项功能的使用场合

有关如何使用TouchGFX四项Flash功能的技术信息和指南,请点击此处:

上述四项功能均可帮助减少应用程序所需的Flash存储器空间。 各项功能的使用具体取决于应用场景,但也可运用一些通用规则来判断。 现在我们将对此进行讨论。

L8和压缩

如果要在位图上使用L8图像格式,位图最多为256色。 L8格式的素材渲染会采用Chrom ART硬件加速,这意味着L8位图的渲染时间几乎与常规位图相同。 有时,与常规位图相比,以L8格式渲染位图甚至更快,这是因为从Flash存储器读取的数据更少。 与32位色深的普通位图相比,L8可以节约70%以上的Flash空间。

与L8相比,图像压缩能帮助您节约更多的Flash空间。 两种图像压缩格式:L8压缩和RGB压缩。 在位图上使用L8压缩,位图首先需要采用L8格式,因为L8压缩算法使用查色表。 所以,L8压缩位图最多256色。 有些L8压缩算法会对最大色彩量有进一步的限制。 L4最多16色,而L8 RLE最多64色。 RGB压缩不要求位图为L8格式,因此可用于所有位图。 与使用Chrom ART硬件加速的L8位图渲染相反,压缩位图(L8-和RGB压缩位图)的渲染是软件实现的,因此渲染成本更高。 压缩位图的另一个限制,是其无法用于可缩放或旋转的控件。

如果您已经拥有PNG格式的素材,则可轻松使用L8图像格式和图像压缩。 通常,您可以在最多256色的位图上使用L8图像格式,而不会有任何显著的性能损失。 如需节约更多Flash空间且渲染时间满足所需的性能,也可使用L8图像压缩。 如压缩与L8格式不兼容的位图,则可使用RGB压缩。 如需要在可伸缩或可旋转的控件中使用位图,则不能在本地使用压缩位图。 当然,有一些方法可以解决这一问题,我们稍后将进行简要介绍。

SVG

另一个节约Flash空间的方法是将其保存为SVG格式,而非PNG格式。 SVG对颜色的数量无限制。 然而,与L8和压缩相比,SVG的渲染成本通常更高。 因此,建议限制同时使用的SVG数量,并将包含SVG的动画保持在最少。 SVG素材越简单,占用的Flash空间就越小,并且可以获得更好的性能。 为此,建议使用单层SVG。

要在SVG控件中使用它,需要以SVG格式导入该素材。 TouchGFX无法转换此类素材。

矢量字体

对于SVG格式的非字体资产,矢量字体的渲染成本也很高,因其渲染方式与SVG相同。 矢量字体通常适用于大字体或同一种字体有多种不同尺寸的情况。 如果您有不同尺寸的矢量字体和矢量表示,只需要存储一次字体。 然后,只需要一个缩放因子便可用不同的尺寸来表示。 对于位图字体,每个字体大小都需要单独存储。 矢量字体节约的Flash空间通常不亚于图像压缩和SVG。 因此,如有必要将Flash存储器占用空间限制在绝对最小值,则应使用矢量字体。

示例

为了提供不同功能特征的具体示例,以常规位图、L8、L8 RLE压缩、RGB压缩和SVG格式对电动自行车演示中的两种图片进行了性能测量。 测量在STM32U5G9J-DK2上进行,素材位于内部Flash。 对于没有NeoChrom GPU的MCU,SVG的渲染时间将更长。 然而,更快的CPU可弥补这一点。

以下资产的色深为32位,是一个顶部有图标的按钮。 按钮为122 x 112像素,图标为72 x 72像素。

电动自行车演示中带图标的按钮

对素材执行以下测量:

格式大小百分比渲染时间CPU负荷
位图:75.4 KB100%0.414 ms2.4%
L8:19.3 KB25.6%0.448 ms2.3%
L8 RLE:2.55 KB3.4%1.51 ms9.6%
RGB:4.53 KB12.0%1.65 ms10.5%
SVG:3.01 KB4.0%1.43 ms4.1%

由此可见,L8 RLE占用的Flash空间最少,但与常规位图格式相比,渲染时间大约要长1毫秒。

以下素材的色深为32位,是演示中仪表板页面中仪表的一部分。 150 x 436像素。

电动自行车演示中仪表的一部分

对素材执行以下测量:

格式大小百分比渲染时间CPU负荷
位图:261.6 KB100%1.15 ms1.5%
L8:65.6 KB25.1%1.24 ms1.4%
L8 RLE:4.66 KB1.78%2.75 ms15.0%
RGB:10.5 KB4.01%3.08 ms17.6%
SVG:0.686 KB0.27%3.40 ms2.0%

SVG格式的资源占用的Flash空间最少,但渲染成本也最高。

结论

如上所述,没有一种格式适合所有资产。 然而,单就节约Flash空间而言,当素材相对较小时,L8图像压缩通常占用的Flash空间最小,而当素材较大时,SVG占用的Flash空间最小。 尽管SVG资产的颜色可以超过256色,但出于Flash存储器使用和性能方面的考虑,仍然建议SVG资产保持相对简单。 在L8、图像压缩和SVG中,L8图像格式占用的Flash空间最大,但L8的渲染时间最短。

因此,在开发Flash资源有限的应用程序时,您需要确定瓶颈并确定什么对您的应用程序最重要。 性能还是Flash存储器空间节约量? 如果是性能,L8将是最有效的方法。 如果性能允许,L8甚至可以与某些素材的压缩相结合。 如果需要尽可能小的Flash占用空间,那么建议使用图像压缩和SVG。

使用“智能”素材

使用“智能”素材可提高Flash空间节约量和性能。 在这里,智能素材指的是素材本身及其用途。

简单素材

首先,素材越简单,可压缩的素材就越多,SVG定义也就越简单, 最终占用的Flash空间会更小。

作为参考,在电动自行车演示中,所有位图资产最多为64色,并且由于这些素材也非常适合L8 RLE,因此所有位图素材都经过L8 RLE压缩。 由于L8 RLE的渲染速度比L8 LZW9更快,因而也能达到理想性能。

此外,如果设计本身较为简单,那么在某些情况下也可使用平铺图像。 然后,您只需要存储图像的一部分,便可重复存储。

使用boxes

另一种以智能方式节约Flash存储器空间的方法是使用Box控件。 使用boexes有两大优势:

  1. 首先,box将直接绘制在帧缓冲器中。 因此,无需Flash存储器来储存box。 对Flash的唯一影响来自定义box所需的少量代码。
  2. 其次,box可调整且可在运行时改变颜色和大小。 在Flash有限的电动自行车演示中,box用于纯色背景等,通过改变方框颜色即可支持亮/暗模式。

可重复使用的素材

另一种节约Flash存储器空间的方法是限制素材总数。 当然,这可以通过非常简单的设计来实现,但有时也可以通过多次重复使用同一素材来限制现有的素材数量。

例如,在Flash使用率有限的电动自行车演示中,该方法可用于天气页面。 天气图标是经过缩放可适应所有3种尺寸的相同资源。 由于它是一种缩放资产,因此SVG格式优于压缩格式,即使RLE的Flash占用空间较小。 然而,如果素材以RLE格式存储在所有3种大小中,则Flash空间的总占用量将更大。

此外,这些按钮还能作为可重复使用的素材来实现。 例如,将按钮与其图标分开,以便重复使用。

在演示中可重复使用的另一个例子是背景。 演示中总共有5种不同的背景设计,但通过使用可调整的素材(Box和可重复使用的素材),所有背景仅需一项素材和一Box即可创建。

提高性能

开发Flash使用率有限的应用程序时,存在降低性能的风险。 但是,如有可用的备用RAM,则有办法提高应用程序的性能。 通过使用动态位图可缓存容器,将素材或容器的静态快照绘制到RAM中。 之后,无论何时使用资产或容器,均可用缓存版本。 缓存版本只是RAM中的一个位图,这意味着渲染时间与渲染常规位图相同。

在限制Flash使用率受限的电动自行车演示中,可缓存容器用于滚动SVG资产和矢量字体,同时保持良好的性能。

天气元素作为可缓存容器

通常,矢量字体在运行时移动或可移动时都会被缓存。 由此确保了在滚动矢量字体的情况下至少有30 FPS。

演示中使用的另一个技巧是将压缩位图解压缩到位图缓存中。 通过将位图解压缩到RAM,就可以在缩放或旋转的控件中使用此位图了。 当位图被解压缩时,TouchGFX引用位图ID时将始终使用解压缩的缓存版本。 下面是电动自行车演示的一个例子。 压缩的位图被简单地解压缩之后,便可以像常规位图那样使用。

StartView.cpp
StartView::StartView()
{
Bitmap::decompress(BITMAP_MAIN_RIPPLE_LEFT_ID); // Decompress compressed image to bitmap cache
Bitmap::decompress(BITMAP_MAIN_RIPPLE_RIGHT_ID); // Decompress compressed image to bitmap cache
}

void StartView::setupScreen()
{
leftMainRippleScale.setBitmap(BITMAP_MAIN_RIPPLE_LEFT_ID); // Set bitmap for Scalable Image
rightMainRippleScale.setBitmap(BITMAP_MAIN_RIPPLE_RIGHT_ID); // Set bitmap for Scalable Image
leftMainRippleScale.setWidthHeight(0, 0); // Set scale of image
rightMainRippleScale.setWidthHeight(0, 0); // Set scale of image
}

由于广泛使用动态位图,Flash使用率受限的电动自行车演示需要922KB的位图缓存。 这意味着需要大量的备用RAM。 然而,该演示也将Flash空间节约到了一个相当极端的程度。 在更简单的应用程序或性能要求不那么重要的应用程序中,可以使用更小的位图缓存。

结论

在本文中,我们了解了如何节省TouchGFX应用程序的Flash用量。

4项Flash节约功能可在所有STM32硬件平台上使用,但请记住,SVG和矢量字体的渲染成本很高。 所以,如果没有矢量渲染的硬件加速或额外的计算能力,性能可能会因此降低。

限制Flash使用率GUI开发的功能可能会导致性能损失,但可以通过使用动态位图和可缓存容器来提高性能。

Flash空间节约功能使节约Flash空间拥有巨大的潜力。 这些功能可节约的实际Flash量取决于具体的应用,而对于Flash使用率受限的电动自行车演示,可节约92%的使用率。