C
Qt Quick ウルトラライトカメラ 使用例
プラットフォーム固有の画像データをQML UIと統合する方法を示します。
概要
この例では、プラットフォーム固有の画像データの扱い方を示します。Qul::SharedImage を用いてカメラを制御し、フレームにアクセスするためのシンプルなユーザインタフェースを備 えています。この例では、サポートされているボードのカメラハードウェアと、その他のボードのダミー実装を使用します。




対象プラットフォーム
プロジェクト構成
サンプルは、シンプルなUI(camera.qml)、カメラインターフェース定義(camerainterface.h)、NXP プラットフォーム用のカメラインターフェースの実装、カメラインターフェースのダミー実装(platform ディレクトリ)で構成されています。さらに、背景画像アセット(bg_qt.png)があります。
CMakeプロジェクトファイル
Qt Quick UltraliteアプリケーションのCMakeセットアップに加え、NXP およびダミーのカメラインターフェース実装を含むプラットフォームサブディレクトリが含まれています。
add_subdirectory(platform)
QmlProjectファイルでは、Qt Quick Ultraliteがカメラインターフェースを見つけられるように登録します。
InterfaceFiles {
files: [
"camerainterface.h"
]
}platformディレクトリのCMakeLists.txtは実装を選択する前にプラットフォームをチェックします:
# Copyright (C) 2025 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial
message(STATUS "Board manufacturer: ${BOARD_MANUFACTURER_NAME}")
string(REGEX MATCHALL "([^\-]+|[^\-]+$)" PLATFORM_COMPONENTS ${QUL_PLATFORM})
list(GET PLATFORM_COMPONENTS 0 BOARD_NAME)
string(TOLOWER ${BOARD_NAME} BOARD_NAME)
if(NOT ${BOARD_NAME} STREQUAL "mimxrt1170" AND ${BOARD_MANUFACTURER_NAME} STREQUAL "nxp")
add_subdirectory(nxp)
else()
add_subdirectory(dummy)
endif()このサンプルはMCUXpresso SDKが提供するコードに依存しています。そのコードをQt Quick Ultraliteプラットフォーム・ライブラリに追加する代わりに、サンプルに追加します。このコードは主にCSIピンmux設定とカメラI2C機能を扱います。また、カメラサポートコードとドライバはMCUXpresso SDKからコンパイルされます。
アプリケーションUI
ユーザーインターフェースはcamera.qmlに実装されています。
アプリケーションは背景画像とカメラ開始ボタンを表示して起動します。ボタンをクリックすると、カメラ画像ストリームが開始され、撮影ボタンと停止ボタンが有効になります。Shootボタンをクリックすると、表示されていたフレームまでカメラ・ストリームが停止し、MinimizeボタンとCloseボタンが有効になります。最小化ボタンは現在表示されているフレームを右上に最小化し、閉じるボタンは前の状態を有効にします。Stopボタンをクリックすると、カメラ・ストリームが停止し、開始状態に戻ります。
ユーザー・インターフェース・コードの興味深い部分は、cameraView Image タイプです:
Text { id: message color: "red" font.pixelSize: 14 } Image { id: cameraView anchors.right: parent.right anchors.top: parent.top source: CameraInterface.image width: 0 height: 0 Behavior on width { NumberAnimation { duration: 500; easing.type: Easing.OutCubic } } Behavior on height { NumberAnimation { duration: 500; easing.type: Easing.OutCubic } } Component.onCompleted: { if (!CameraInterface.initCamera()) { console.log("Camera initialization failed"); message.text = "Camera initialization failed.\nConnect a camera and/or check the serial console output."; } } SequentialAnimation on opacity { id: shootAnimation PropertyAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200} PropertyAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 200} } }
これは、カメラ・インターフェースのimage プロパティをsource プロパティにバインドします。また、イベント・ハンドラからinitCamera() を呼び出してカメラを初期化します。
カメラ・インターフェース
カメラ・インターフェースは、Qul::EventQueue を持つ単純なQul::Singleton インターフェースです。イベント・キューは、プラットフォームからQt Quick Ultralite アプリケーションにカメラ・フレームを非同期に配信するために使用されます。
まず、カメラ・フレーム・データへのポインタを保持する単純な構造体が定義されます:
struct FrameEvent { uint8_t *newFrame; };
この構造体はQul::EventQueue のイベント・データ型として使用されます。
以下はカメラ・インターフェースの定義です:
struct CameraInterface : public Qul::Singleton<CameraInterface>, public Qul::EventQueue<FrameEvent> { Qul::Property<Qul::SharedImage> image; bool initCamera(); void startCamera(); void stopCamera(); private: void onEvent(const FrameEvent &frame) QUL_DECL_OVERRIDE; friend struct Qul::Singleton<CameraInterface>; CameraInterface() {} CameraInterface(const CameraInterface &); CameraInterface &operator=(const CameraInterface &); };
まず、カメラ・インターフェースは、Qul::SharedImage タイプのイメージ・プロパティを導入します。このプロパティには、プラットフォーム・カメラ・ストリームのフレーム・データが含まれます。この後、カメラを制御する関数が宣言されます。initCamera()関数はプラットフォーム・カメラを初期化し、startCamera()関数とstopCamera()関数はカメラ・ストリームを開始および停止します。Qul::EventQueue のonEvent()関数は、画像の更新を処理するためにオーバーライドされます。最後に、外部からの構築とコピーが防止されます。
カメラ・インターフェースの実装
カメラ・インターフェースの実装はプラットフォーム・ディレクトリにあります。ダミーのサブディレクトリにはダミーの実装があり、インターフェースのスタブ関数を実装しています。これはサンプルを他のプラットフォームに移植する際の出発点として使用できます:
#include "camerainterface.h" /* Initialize your platform's camera hardware in this function. */ bool CameraInterface::initCamera() { return false; } /* Start camera stream. */ void CameraInterface::startCamera() {} /* Stop camera stream. */ void CameraInterface::stopCamera() {} /* When the camera frame is ready, the image property can be updated in this event handler. */ void CameraInterface::onEvent(const FrameEvent &frameEvent)
nxpサブディレクトリにはNXP ボード用の実装があります。この実装では、NXP のカメラ・レシーバー API を使用します。initCamera() でカメラ・レシーバーを初期化し、新しいフレームを受信するためのコールバック関数と、this のポインタをユーザー・データとして設定し、Qul::EventQueue を通じてイベントを投稿できるようにします。
err = CAMERA_RECEIVER_Init(&cameraReceiver, &cameraConfig, newCameraFrame, this);
また、空のカメラ・フレーム・バッファもカメラ・レシーバに送信されます。
for (uint32_t i = 0; i < CAMERA_BUFFER_COUNT; i++) { err = CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t) (s_cameraBuffers[i])); RETURN_FALSE_IF(err != kStatus_Success, "Failed to submit camera buffer!"); }
カメラレシーバはnewCameraFrame コールバックを介して新しいフレームを通知します。コールバックは新しいカメラフレームへのポインタを含むFrameEvent 。
me->postEventFromInterrupt(FrameEvent{(uint8_t *) cameraFrameAddr});
FrameEvent はonEvent() で処理され、カスタムクリーンアップ関数を持つQul::Image が構築され、Qul::SharedImage でラップされ、image プロパティの値として設定されます。
image.setValue(Qul::SharedImage(newFrame));
cleanup 関数は、Qt Quick Ultralite エンジンがQul::SharedImage 参照を破棄するときに呼び出されます。関数のmemory 引数は、image プロパティを使用してQt Quick Ultralite エンジンに渡されたバッファを指します。空のバッファは、新しいカメラフレームが利用可能になるたびにアクセスするために再利用されます。
status_t err = CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t) (memory));
ファイル
- camera/CMakeLists.txt
- camera/camera.qml
- camera/camerainterface.h
- camera/mcu_camera.qmlproject
- camera/platform/CMakeLists.txt
- camera/platform/dummy/CMakeLists.txt
- camera/platform/dummy/camerainterface.cpp
- camera/platform/nxp/CMakeLists.txt
- camera/platform/nxp/camerainterface.cpp
- camera/platform/nxp/pin_mux_csi.c
- camera/platform/nxp/pin_mux_csi.h
画像:
Qul::SharedImage,Qul::Image,Qul::EventQueue, およびQul::Singletonも参照してください 。