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 KB | 100% | 0.414 ms | 2.4% |
L8: | 19.3 KB | 25.6% | 0.448 ms | 2.3% |
L8 RLE: | 2.55 KB | 3.4% | 1.51 ms | 9.6% |
RGB: | 4.53 KB | 12.0% | 1.65 ms | 10.5% |
SVG: | 3.01 KB | 4.0% | 1.43 ms | 4.1% |
由此可见,L8 RLE占用的Flash空间最少,但与常规位图格式相比,渲染时间大约要长1毫秒。
以下素材的色深为32位,是演示中仪表板页面中仪表的一部分。 150 x 436像素。
对素材执行以下测量:
格式 | 大小 | 百分比 | 渲染时间 | CPU负荷 |
---|---|---|---|---|
位图: | 261.6 KB | 100% | 1.15 ms | 1.5% |
L8: | 65.6 KB | 25.1% | 1.24 ms | 1.4% |
L8 RLE: | 4.66 KB | 1.78% | 2.75 ms | 15.0% |
RGB: | 10.5 KB | 4.01% | 3.08 ms | 17.6% |
SVG: | 0.686 KB | 0.27% | 3.40 ms | 2.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有两大优势:
- 首先,box将直接绘制在帧缓冲器中。 因此,无需Flash存储器来储存box。 对Flash的唯一影响来自定义box所需的少量代码。
- 其次,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空间节约到了一个相当极端的程度。 在更简单的应用程序或性能要求不那么重要的应用程序中,可以使用更小的位图缓存。
Further reading
结论
在本文中,我们了解了如何节省TouchGFX应用程序的Flash用量。
4项Flash节约功能可在所有STM32硬件平台上使用,但请记住,SVG和矢量字体的渲染成本很高。 所以,如果没有矢量渲染的硬件加速或额外的计算能力,性能可能会因此降低。
限制Flash使用率GUI开发的功能可能会导致性能损失,但可以通过使用动态位图和可缓存容器来提高性能。
Flash空间节约功能使节约Flash空间拥有巨大的潜力。 这些功能可节约的实际Flash量取决于具体的应用,而对于Flash使用率受限的电动自行车演示,可节约92%的使用率。