QML カメラアプリケーション
このQt Quick ベースのアプリケーションは、APIを使用して静止画や動画を撮影する方法を示しています。

この例では、QML を通じてカメラ機能にアクセスする方法を示しています。設定の変更や、静止画・動画のキャプチャ方法についても説明しています。
例の動作確認
以下の手順でサンプルを実行できます。
- Qt Creator
Welcome モードを開き、「Examples 」からこの例を選択します。詳細については、Qt Creator の「チュートリアル: ビルドと実行」を参照してください。
- Qt Extension for Visual Studio Code
Command Palette から `Qt: Open Qt examples ` コマンドを実行し、リストからこのサンプルを選択します。詳細については、Qt Extension for Visual Studio Code の「チュートリアル: ビルドと実行」を参照してください。
アプリケーションの構造
この例の QML コードの大部分は、ユーザーインターフェースをサポートするものです。要件を満たすカスタム型は、既存のQt Quick コントロールを使用して実装されています。
画面の向きに基づくレイアウトの選択
画面の向きとコントロールのレイアウト状態に関するロジックは、次のように、別の Item(controlLayout )にカプセル化されています。
Item {
id: controlLayout
readonly property bool isMobile: Qt.platform.os === "android" || Qt.platform.os === "ios"
readonly property bool isLandscape: Screen.desktopAvailableWidth >= Screen.desktopAvailableHeight
property int buttonsWidth: state === "MobilePortrait" ? Screen.desktopAvailableWidth / 3.4 : 114
states: [
State {
name: "MobileLandscape"
when: controlLayout.isMobile && controlLayout.isLandscape
},
State {
name: "MobilePortrait"
when: controlLayout.isMobile && !controlLayout.isLandscape
},
State {
name: "Other"
when: !controlLayout.isMobile
}
]
onStateChanged: {
console.log("State: " + controlLayout.state)
}
}stillControls に示されているように、stillControls およびvideoControls オブジェクトは、いずれもこのItemのstate およびbuttonsWidth プロパティにバインドされています:
PhotoCaptureControls {
id: stillControls
state: controlLayout.state
anchors.fill: parent
buttonsWidth: controlLayout.buttonsWidth
buttonsPanelPortraitHeight: cameraUI.buttonsPanelPortraitHeight
buttonsPanelWidth: cameraUI.buttonsPanelLandscapeWidth
captureSession: captureSession
visible: (cameraUI.state === "PhotoCapture")
onPreviewSelected: cameraUI.state = "PhotoPreview"
onVideoModeSelected: cameraUI.state = "VideoCapture"
previewAvailable: imageCapture.preview.length !== 0
}デバッグを支援するため、レイアウト状態の変更に関するメッセージがログに記録されます。
以下は縦向きレイアウトです:

state プロパティが、初期状態でPhotoCapture に設定されていることがわかります。
そして、states 自体は次のように定義されています:
states: [
State {
name: "PhotoCapture"
StateChangeScript {
script: {
camera.start()
}
}
},
State {
name: "PhotoPreview"
},
State {
name: "VideoCapture"
StateChangeScript {
script: {
camera.start()
}
}
},
State {
name: "VideoPreview"
StateChangeScript {
script: {
camera.stop()
}
}
}
]キャプチャ用コントロール
キャプチャ用コントロールは、PhotoCaptureControls.qml およびVideoCaptureControls.qmlで実装されています。これらはそれぞれ、コントロールボタンで使用される共通のボタン寸法やマージンを定義し、その後ボタンを宣言するFocusScope を基にしています。
これにより、画面の右側に列が生成され、上から順に以下のコントロールが含まれます:
CaptureまたはRecordボタン。キャプチャを開始します。capture propertiesボタン。現在選択されているホワイトバランスモードのアイコンを表示し、押すとポップアップが表示され、以下のオプションのアイコンが表示されます:- フラッシュモード(利用可能な場合)
- ホワイトバランスモード
- 露出補正
Viewボタン(何かが撮影された後)。- 現在選択されている撮影デバイスを表示し、押すとポップアップで切り替え可能なデバイスのリストを表示するボタン。
Switch Toボタン。現在アクティブな選択に応じて、別のキャプチャモード(動画または写真)を表示し、押すとモードを切り替えます。- アプリケーションを終了する「
Quit」ボタン。


画像のキャプチャ
これを起動するボタンは CameraButton.qml で定義されていますが、カメラとの連携はコントロールタイプ側で行われています。PhotoCaptureControls を見てみましょう:
CameraButton {
text: "Capture"
implicitWidth: captureControls.buttonsWidth
visible: captureControls.captureSession.imageCapture.readyForCapture
onClicked: captureControls.captureSession.imageCapture.captureToFile("")
}ズームコントロール
ZoomControl.qml で実装されているZoomControlタイプはItemを基にしており、ズームレベルを表すバーを作成します。このバーはドラッグすることも可能です。grove の位置に基づいてズーム倍率を決定するために、指数関数的な計算方法を使用しています。
このバーは、initialZoomが1より大きい場合にのみ表示されます。これは、現在アクティブなカメラにズーム機能があることを意味します。

Item {
id : zoomControl
property real currentZoom : 1
property real maximumZoom : 1
property real minimumZoom : 1
signal zoomTo(real target)
visible: zoomControl.maximumZoom > zoomControl.minimumZoom
MouseArea {
id : mouseArea
anchors.fill: parent
property real initialZoom : 0
property real initialPos : 0
onPressed: {
initialPos = mouseY
initialZoom = zoomControl.currentZoom
}
onPositionChanged: {
if (pressed) {
var target = initialZoom * Math.pow(5, (initialPos-mouseY)/zoomControl.height);
target = Math.max(zoomControl.minimumZoom, Math.min(target, zoomControl.maximumZoom))
zoomControl.zoomTo(target)
}
}
}
Item {
id : bar
x : 16
y : parent.height/4
width : 24
height : parent.height/2
Rectangle {
anchors.fill: parent
smooth: true
radius: 8
border.color: "white"
border.width: 2
color: "black"
opacity: 0.3
}
Rectangle {
id: groove
x : 0
y : parent.height * (1.0 - (zoomControl.currentZoom-zoomControl.minimumZoom) / (zoomControl.maximumZoom-zoomControl.minimumZoom))
width: parent.width
height: parent.height - y
smooth: true
radius: 8
color: "white"
opacity: 0.5
}
Text {
id: zoomText
anchors {
left: bar.right; leftMargin: 16
}
y: Math.min(parent.height - height, Math.max(0, groove.y - height / 2))
text: "x" + Math.round(zoomControl.currentZoom * 100) / 100
font.bold: true
color: "white"
style: Text.Raised; styleColor: "black"
opacity: 0.85
font.pixelSize: 18
}
}
}PhotoCaptureControls.qml および VideoCaptureControls.qml において、zoomTo シグナルは、選択されたカメラのzoomFactor プロパティを、計算されたtarget 値に設定するとともに、ZoomControl バーを更新します。
ZoomControl {
x : 0
y : 0
width : 100
height: parent.height - (flashControl.visible * flashControl.height) -
(captureControls.state === "MobilePortrait" ? buttonPaneShadow.height : 0)
currentZoom: captureControls.camera.zoomFactor
maximumZoom: captureControls.camera.maximumZoomFactor
minimumZoom: captureControls.camera.minimumZoomFactor
onZoomTo: (target) => captureControls.camera.zoomFactor = target
}フラッシュおよび懐中電灯の制御

FlashControl.qml で定義されており、これによりスイッチを介してフラッシュモードの選択や懐中電灯機能の切り替えが可能になります。ズームコントロールと同様に、これらのスイッチは、アクティブなデバイスがこれらの機能をサポートしている場合にのみ、プレビューウィンドウの上に表示されます。
ここでは、これらの機能がサポートされているかどうかを確認します:
required property Camera camera
property bool mIsFlashSupported: camera.isFlashModeSupported(Camera.FlashOn)
property bool mIsTorchSupported: camera.isTorchModeSupported(Camera.TorchOn)ここでは、flashModeControl のスイッチを実装します。このスイッチは、Cameraデバイスを直接制御します。
Switch {
id: flashModeControl
visible: topItem.mIsFlashSupported
checked: topItem.camera.flashMode === Camera.FlashOn
opacity: checked ? 0.75 : 0.25
text: "Flash"
contentItem: Text {
text: flashModeControl.text
color: "white"
leftPadding: flashModeControl.indicator.width + flashModeControl.spacing
}
onClicked: topItem.camera.flashMode = checked ? Camera.FlashOn : Camera.FlashOff
}トーチ制御も同様の方法で実装されます。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.