このページでは

C

リソースの管理

このトピックでは、Qt Quick Ultraliteアプリケーションが画像リソースをどのように利用するかについて説明します。

フォントリソースは、リソースシステムを通じて追加されることはありません。フォントの取り扱いに関する詳細については、「テキストのレンダリングとフォント」を参照してください。

画像のキャッシュ」に関するトピックも参照してください。

まとめ

Qt Quick Ultralite アプリケーションでリソースを使用するには、QmlProject API を使用してそれらを宣言する必要があります。

Resource Compiler(qulrcc ツール)は、リソース宣言を使用して、組み込み用のコンテンツを準備します。この際、生のリソースデータに対して最適化を行う場合があります。たとえば、画像の最適化では、色深度の低減、アルファマップへの置換、輪郭の透明部分の削除、スウィズリングなどが行われることがあります。

リソースシステムへのファイルの追加

Qt Quick Ultralite アプリケーションにリソースを追加するには、QmlProject のImageFiles.filesプロパティを使用します。

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 です。Image 内で、source という URI を使用することで、これを表示できます:

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マニュアル』を参照してください。

次の例では、ImageFiles.MCU.resourceCompression を設定することで、大きなbackground.pngを圧縮形式で保存し、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.platformOpaqueCompressedLosslessResourcePixelFormatおよびMCU.Config.platformAlphaCompressedLosslessResourcePixelFormatの設定に基づいて、最適な形式が自動的に選択されます。

AutomaticCompressedLossless を使用する利点は、画像を画像キャッシュに展開することなく、ブレンド処理中にその場でデコードできることです。つまり、ImageFiles.MCU.resourceCompression を使用する画像に比べて、必要な揮発性メモリが少なくて済みます。

ただし、平均圧縮率はそれほど高くなく、変換された画像はサポートされていません。また、ほとんどのプラットフォームで CPU フォールバックを使用するため、ブレンド性能に悪影響を及ぼす可能性があります。 通常、半透明ピクセルを多く含む画像のブレンドや、計算されたItem::opacity の値が1未満の場合、CPUによる処理は低速になります。RLEピクセル形式のハードウェアアクセラレーションによるブレンドをサポートしているプラットフォームについては、「サポートされている機能」の表を参照してください。

次の表は、2つのサンプル画像と、それらの非圧縮サイズおよび圧縮(RLEまたはPNG)サイズを示しています。 最初の画像は、同じピクセル値を含む連続した領域があるため、圧縮効率がはるかに高くなっています。このような画像をImageFiles.MCU.resourceCompressionを使用して PNG に圧縮すると、さらに高い圧縮率を得ることができますが、画面に描画する前に、画像キャッシュに展開する必要があります。

画像

非圧縮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 圧縮 - すべての非圧縮画像リソースを格納するのに必要なメモリが十分でないプラットフォームの場合。画像キャッシュが、画面上に同時に表示されるすべての画像を収容できる十分な大きさであれば、必要な画像がすべて揮発性メモリ内にあるため、アニメーションのパフォーマンスは良好になります。
  • AutomaticCompressedLossless あるいは、キャッシュを使用せずに画像をフラッシュメモリに保持する非圧縮画像。揮発性メモリが限られているプラットフォームでは、PNG圧縮は選択肢にならないため、これら2つの手法のいずれかが理想的です。

特定の画像リソースに対してロスレス圧縮を有効にする方法は以下の通りです:

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

メモリ内でのリソースの配置

デフォルトでは、リソースはQulResourceData という名前の予約済みメモリ領域に配置されます。ImageFiles.MCU.resourceStorageSectionプロパティを設定することで、リソースを別のストレージ領域に配置することができます。ImageFiles.MCU.resourceCachePolicyプロパティは、リソースが揮発性メモリに読み込まれるタイミングと方法を制御します。 異なる種類の揮発性メモリ(RAM、VRAM、HyperRAMなど)が利用可能な場合、ImageFiles.MCU.resourceRuntimeAllocationTypeプロパティを使用して、特定のリソースに使用する揮発性メモリ領域を選択できます。

次の例では、3つの画像がArrows という名前のメモリセクションに格納されています。

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

OTAリソースの更新

ユーザーが一部のリソースの無線(OTA)更新を行いたい場合、これらのリソースは、前述の「メモリ内でのリソースの配置」で示したように、特定のメモリセクション(例:OTAResourceSection )に配置する必要があります。

ユーザーがホスト上でOTA更新の対象となるイメージを更新すると、特定のターゲットアプリケーションに対して、OTAResourceSection のバイナリコンテンツを再生成することが可能になります。

このようなバイナリの生成はResource Compilerによって行われ、CMake を通じて次のように呼び出すことができます:

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

アプリケーション全体を再コンパイルする必要はありません。リソースバイナリはqul_resources_<section_name>.bin という名前(例:qul_resources_OTAResourceSection.bin )で、ターゲットアプリケーションのビルドフォルダ内に保存されます。

一部の画像は、ImageFiles.MCU.resourceCachePolicy によってキャッシュ(OnDemand )されるか、起動時にプリロード(OnStartup )される可能性があるため、OTA アップデートに含まれる画像をアプリケーションで実際に利用するには、Qt Quick Ultralite アプリケーションを再起動する必要があります。

アプリケーションの起動時、Qul::initResources() の戻り値を使用して、リソースの初期化が成功したかどうかを確認できます。失敗した場合は、更新されたリソースデータが破損しているか、アプリケーションが当初ビルドされた際のリソースデータと互換性がないことを示している可能性があります。 互換性を確保するため、リソースのパスはすべて元のリソースデータと一致している必要があります。変更が許可されるのは、リソースの設定および実際の画像コンテンツのみです。

注: `OnDemand ` キャッシュポリシーまたは `ImageFiles.MCU.resourceCompression` を使用する画像については 、アプリケーションが当初ビルドされた際のリソースキャッシュのサイズ内に収まることを確認してください。

リソースデータのチェックサム検証

リソースの初期化中にリソースのバイナリデータに対してチェックサム検証を実行するには、まずQul::enableResourceChecksumVerification()関数を使用してリソースのチェックサム検証を有効にする必要があります。

リソースデータのバージョン管理

また、リソースのバイナリデータに対してメジャーバージョンとマイナーバージョンを指定することも可能です。その場合、Qul::initResources() は、読み込まれたリソースデータのメジャーバージョンとマイナーバージョンを、アプリケーションが最初にビルドされた際のメジャーバージョンとマイナーバージョンと比較します。

読み込まれたリソースデータのメジャーバージョンがアプリケーションのメジャーバージョンより低い場合、またはメジャーバージョンは一致しているもののマイナーバージョンがアプリケーションのマイナーバージョンより低い場合、Qul::ResourceInitializationError::VersionTooLow が返されます。

読み込まれたリソースデータのメジャーバージョンがアプリケーションのメジャーバージョンより高い場合、Qul::ResourceInitializationError::VersionTooHigh が返されます。

読み込まれたリソースデータのメジャーバージョンがアプリケーションのメジャーバージョンと等しく、かつ読み込まれたリソースデータのマイナーバージョンがアプリケーションのマイナーバージョン以上である場合、そのバージョンは有効であるとみなされます。

バージョンは、.qmlproject ファイル内でResourceStorageSection.majorVersionおよびResourceStorageSection.minorVersionAPI を使用して手動で指定する必要があります。例:

MCU.Config {
        ResourceStorageSection
        {
            name: "OTAResourceSection"
            majorVersion: 2
            minorVersion: 1
        }
}

注記

  • Qt Quick Ultralite では、新しいバイナリデータの生成以外に、データをフラッシュメモリに書き換えるための直接的な仕組みは提供されていません。アプリケーション固有のソリューションを実装する必要があります。
  • リソースのバイナリコンテンツはリトルエンディアン形式です。
  • ファイル名は、もともとQMLアプリケーションで使用されていたものと一致させる必要があります。一致しない場合、リソースの検索に失敗します。
  • 他のメモリ領域を上書きしないようにするため、OTA アップデートのセクション部分はフラッシュメモリの最後に配置する必要があります。
  • フラッシュメモリは、ブロック単位で消去および書き換えを行う必要があります。バイナリデータの開始位置と終了位置がブロックの境界に正確に一致しない場合、消去されるメモリブロック内の古いデータを読み取る必要がある可能性があります。使用しているフラッシュツールやライブラリがこれを自動的に処理しない場合は、この点に十分注意してください。

スプライトアニメーションのリソースプロパティ

スプライトアニメーションには、コンパイル時の前処理が伴います。リソースプロパティは、この処理に有用な情報を提供し、リソースの最適化を可能にします。

アニメーションのソースとなるディレクトリ

スプライトアニメーションのソースとして、一連の画像ファイルが含まれるディレクトリを指定できます。AnimatedSpriteDirectory というQML型を使用すると、これらの画像ファイルをロードしてレンダリングできます。.qmlproject ファイル内で、これらの画像ファイルにImageFiles.MCU.resourceAnimatedSpriteタグを付与することで、コンパイル時にディレクトリ名を識別できるようになります。

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

これにより、画像ファイルのディレクトリを特定し、それを `AnimatedSpriteDirectory` の `sourcePath ` として使用できるようになります。以下の例は、その方法を示しています:

import QtQuickUltralite.Extras

AnimatedSpriteDirectory {
    sourcePath: "loading"
}

スプライトアニメーションのリソース最適化

スプライトアニメーションの画像ファイルを個別に分割することで、コンパイル時に一連の画像を分析した後、リソースの保存容量を最適化することができます。Resource Compiler(qulrcc ツール)は、画像から共通部分を特定し、それらを再利用することでメモリ使用量を削減します。

AnimatedSprite というQMLタイプの画像ソースに対して、ImageFiles.MCU.resourceAnimatedSpriteFrameWidthおよび ImageFiles.MCU.resourceAnimatedSpriteFrameHeightを指定することで、フレームを個別に分割することによるすべてのメリットを享受できます。

Qt Quick のUltralite sprite_animationsサンプルではqt-image-sequence.pngには16フレームが含まれています。 画像ソースに対してImageFiles.MCU.resourceAnimatedSpriteFrameWidthおよびImageFiles.MCU.resourceAnimatedSpriteFrameHeightを設定すると、Resource Compiler は内部で 16 フレームを生成します。

フレーム #0

フレーム #1

フレーム #2フレーム #3

フレーム #3

フレーム #4

フレーム #5

フレーム #6

フレーム #7

フレーム #8

フレーム #9

フレーム #10

フレーム #11

フレーム #12

フレーム #13

フレーム #14

フレーム #15

この前処理により、アプリケーションは画像ソースよりもはるかに小さい画像サイズの各フレームのみを読み込むため、画像ソースの実行時のメモリ使用量が削減されます。また、Resource Compilerも、フレームシーケンス間で共通部分を共有することで、同様の最適化を行います。

外部ストレージからのリソース

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、現在テクノロジープレビュー段階にあります。今後のリリースで変更される可能性があります。

外部ストレージからのアセットの読み込みには、潜在的なセキュリティ上の脅威があります

警告: 外部ストレージからアセットを読み込むと 、デバイスに対する攻撃の経路が生じます。

Qt Quick Ultraliteは、アセット自体や、それらが読み込まれるファイルシステムの検証を行いません。外部ストレージ上の改ざんされたデータが、デバイスを侵害するために悪用される可能性があります。

ファイルシステムから読み込まれるデータが有効であることを確認するのは、ユーザーの責任です。これには、物理的にアクセスを遮断するか、起動フェーズ中に暗号技術を用いて検証を行うなどの方法があります。

考えられる攻撃対象領域には、以下が含まれます。

  • 画像データが無効な場合のPNGおよびRLEデコーダ。
  • 無効なデータブロックが存在する場合のファイルシステムの実装。
  • 画像サイズが大きすぎる場合、またはデータが宣言されたサイズと一致しない場合の、レンダリングおよびメモリ管理。

関連項目: ImageFiles.MCU.resourceImagePixelFormatMCU.Config.binaryAssetOptionsImageFiles.MCU.prefix、およびImageFiles.MCU.resourceCompression

特定のQtライセンスの下で利用可能です。
詳細はこちらをご覧ください。