C

管理资源

本主题介绍了 Qt Quick Ultralite 应用如何使用图片资源。

字体资源不是通过资源系统添加的。有关字体处理的更多信息,请参阅文本渲染和字体

另请参阅图片缓存主题。

总结

要在 Qt Quick Ultralite 应用中使用资源,您必须使用 QmlProject API 声明它们。

资源编译器(qulrcc工具)使用资源声明来准备包含的内容。它可能对原始资源数据进行优化。例如,图像优化可能导致降低颜色深度,以着色图替换,删除轮廓透明区域,并进行混色。

向资源系统添加文件

使用 ImageFiles.files QmlProject 属性将资源添加到 Qt Quick Ultralite 应用程序中。

ImageFiles {
    files: ["ui/spinner.png", "background.png"]
}

ImageFiles.files 属性将文件添加到虚拟资源文件系统。文件系统中的资源通过带有可选 "qrc:" 方案的资源 URI 进行引用。

qrc:/
  |-- background.png
  |-- ui/
       |-- spinner.png

在上面的示例中,qrc:/ui/spinner.png 是基于源目录中的 ui/spinner.png 文件的资源 URI。它可以用作 source 属性在 Image 中显示。

Image {
    source: "qrc:/ui/spinner.png"
}

当在资源 URI 中使用相对路径时,路径是相对于虚拟资源文件系统的根目录。URI 的方案可以省略。以下所有 URI 都引用 ui/spinner.png

  • ui/spinner.png
  • /ui/spinner.png
  • qrc:ui/spinner.png
  • qrc:/ui/spinner.png
  • qrc:///ui/spinner.png

资源属性

您可以可选地为使用 ImageFiles.files 列出的图像集合设置资源属性,来自 QmlProject ImageFiles 节点中的可用属性列表。

ImageFiles {
    files: ["image.png"]
    MCU.resourceCompression: true
}

图像资源支持多个资源属性,这些属性控制图像在设备上的存储方式,或可以触发不同的优化。有关完整属性列表,请参阅QmlProject 手册

以下示例中,大图片 background.png 通过设置 ImageFiles.MCU.resourceCompression 以压缩格式存储,而 spinner.png 则带有 ImageFiles.MCU.resourceOptimizeForRotation 标签以优化其在运行时旋转的性能。

ImageFiles {
    files: ["spinner.png"]
    MCU.resourceOptimizeForRotation: true
}
ImageFiles {
    files: ["background.png"]
    MCU.resourceCompression: true
}
Image {
    source: "qrc:/background.png"

    Image {
        anchors.centerIn: parent
        source: "qrc:/spinner.png"
        transform: Rotation {
            NumberAnimation on angle { from: 0; to: 360; running: true; loops: Animation.Infinite }
        }
    }
}

无损压缩图像格式

Qt for MCUs 支持作为 ImageFiles.MCU.resourceCompression 的替代方案使用运行长度编码(RLE)压缩格式。如果图像中有很大部分具有相同的颜色,那么它就很有用。对于 ImageFiles.MCU.resourceImagePixelFormat 属性的 RLE 格式选项有:RGB888RLEXRGB8888RLE 以及 ARGB888RLE

支持的 RLE 格式取决于平台。因此,请使用 AutomaticCompressedLossless 选项,根据平台的 MCU.Config.platformOpaqueCompressedLosslessResourcePixelFormatMCU.Config.platformAlphaCompressedLosslessResourcePixelFormat 设置自动选择理想的格式。

使用 AutomaticCompressedLossless 的好处是图像可以在它们被融合时实时解码,而不需要在 image cache 中解压。这意味着所需的非易失性内存比使用 ImageFiles.MCU.resourceCompression 的图像要少。

然而,平均压缩率并不那么好,且不支持转换图像。它也可能对融合性能产生负面影响,因为大多数平台上都使用 CPU 退回到备用方案。如果包含大量半透明像素或计算出的 Item::opacity 值小于一,CPU 常常较慢地融合图像。有关支持硬件加速融合 RLE 像素格式的平台的详细信息,请参阅 Supported Features 表。

以下表格展示了两个示例图像及其未压缩和压缩(RLE 或 PNG)的大小。第一个图像由于包含相同像素值的连续区域而压缩得更好。使用 ImageFiles.MCU.resourceCompression 将此类图像压缩成 PNG 会产生更好的压缩率,但必须在将其绘制到屏幕上之前在 image cache 中解压缩。

图像

未压缩82.9 kB82.9 kB
RLE 压缩23.2 kB72.6 kB
PNG 压缩6.7 kB27.5 kB

以下是何时使用 PNG 或 RLE 压缩以获得更好的融合性能的某些有用启发式方法

  • OnStartup 缓存策略 - 在具有足够闪存和非易失性内存供应用程序使用的平台上。
  • RLE 压缩 - 在支持硬件加速融合而没有中间缓冲区的平台上。如果性能开销可以接受,也可以在没有硬件加速的平台上使用。
  • 使用 ImageFiles.MCU.resourceCompression 的 PNG 压缩 - 在没有足够内存来存储所有未压缩图像资源的平台上。如果 image cache 足够大,可以同时容纳屏幕上的所有可见图像,动画性能将很好,因为所需的图像都在非易失性内存中。

ImageFiles {
    files: "example.png"
    MCU.resourceImagePixelFormat: "AutomaticCompressedLossless"
}

ImageFiles {
    files: [
        "images/arrow-0.png",
        "images/arrow-45.png",
        "images/arrow-90.png",
    ]
    MCU.resourceStorageSection: "Arrows"
}
Arrows :
{
    . = ALIGN(4);
    *(Arrows)
} > QSPI_FLASH

Arrows :
{
    . = ALIGN(4);
    *(Arrows)
} > QSPI_FLASH

cmake --build . --target <application>_resource_binaries

精灵动画在编译时会涉及到一些预处理。资源属性为这个过程提供了有用的信息,使其能够优化资源。

目录作为动画源

一个精灵动画源可以是包含一系列图像文件的目录,这种目录可以被AnimatedSpriteDirectory QML类型加载和渲染。在.qmlproject文件中使用ImageFiles.MCU.resourceAnimatedSprite标记这些图像文件,以在编译时识别其目录名称。

    ImageFiles {
        files: [
            "loading/01.png",
            "loading/02.png",
            "loading/03.png",
            "loading/04.png"
        ]
        MCU.resourceAnimatedSprite: true
    }

这允许识别图像文件目录并将其作为sourcePath用于AnimatedSpriteDirectory。以下示例演示了如何实现它

import QtQuickUltralite.Extras

AnimatedSpriteDirectory {
    sourcePath: "loading"
}

精灵动画的资源优化

精灵动画的单独图像文件在编译时分析了图像系列后,提供了优化资源存储的机会。资源编译器(qulrcc工具)从图像中找出共同的部分,并重复使用它们以减少内存占用。

AnimatedSprite QML类型的图像源指定ImageFiles.MCU.resourceAnimatedSpriteFrameWidthImageFiles.MCU.resourceAnimatedSpriteFrameHeight可以享受单独帧的所有好处。

Qt Quick Ultralite精灵动画示例中,qt-image-sequence.png有16帧。如果你设置了ImageFiles.MCU.resourceAnimatedSpriteFrameWidthImageFiles.MCU.resourceAnimatedSpriteFrameHeight,资源编译器会自动生成16帧。

帧#0

帧#1

帧#2

帧#3

帧#4

帧#5

帧#6

帧#7

帧#8

帧#9

帧#10

帧#11

帧#12

帧#13

帧#14

帧#15

这种预处理减少了图像源的运行时内存空间,因为应用程序只加载每个比图像源小得多的帧。资源编译器通过在帧序列之间共享共同部分来应用相同的优化。

外部存储的资源

您可以使用MCU.resourceAsFile属性来配置从外部存储加载的资源。

ImageFiles {
    files: [ "2008.png" ]
    MCU.prefix: "logos"
    MCU.resourceAsFile: true
    MCU.resourceCompression: false
}

当启用时,图像将被处理但不包含到资产中。相反,它将作为独立的文件创建,以便手动复制到设备的文件系统上。

您必须使用file://协议来使用这些资源。

Image {
    source: "file://logos/2008.png"
}

您还可以应用其他资产属性,例如向图像路径添加前缀或启用RLE压缩。

注意:Filesystem平台API,该API允许访问本地文件系统上的资源处于技术预览状态。它可能在未来的版本中发生变化。

从外部存储加载资产具有潜在的安全威胁

警告:从外部存储加载资产为设备创建了攻击向量。

Qt Quick Ultralite不会验证资产或加载它们的文件系统。外部存储上的操纵数据可能被用来危害设备。

用户有责任确保从文件系统加载的数据是有效的。这可以通过在启动阶段对它的访问进行物理锁定或进行加密验证来实现。

可能的攻击面包括:

  • 当图像数据无效时,PNG 和 RLE 解码器。
  • 当存在无效数据块时,文件系统实现。
  • 处理大小过大或数据与声明的大小不匹配的图像时的渲染和内存管理。

另请参阅ImageFiles.MCU.resourceImagePixelFormatMCU.Config.binaryAssetOptionsImageFiles.MCU.prefix,以及ImageFiles.MCU.resourceCompression

在某些 Qt 许可证下提供。
了解更多信息。