QML 카메라 애플리케이션
이 Qt Quick 기반 애플리케이션은 API를 사용하여 정지 이미지 또는 동영상을 캡처하는 방법을 보여줍니다.
이 예는 QML을 통해 카메라 기능에 액세스하는 방법을 보여줍니다. 설정을 변경하고 이미지 또는 동영상을 캡처하는 방법을 보여줍니다.
예제 실행하기
에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.
애플리케이션 구조
이 예제의 대부분의 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
및 videoControls
객체는 모두 stillControls
에 표시된 것처럼 이 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
의 위치에 따라 확대/축소 계수를 결정합니다.
이 막대는 초기 줌이 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.captureSession.camera.zoomFactor maximumZoom: captureControls.captureSession.camera.maximumZoomFactor minimumZoom: captureControls.captureSession.camera.minimumZoomFactor onZoomTo: (target) => captureControls.captureSession.camera.zoomFactor = target }
플래시 및 토치 제어
FlashControl.qml
에 정의되어 스위치를 통해 플래시 모드 선택 및 토치 기능을 토글할 수 있습니다. 줌 컨트롤과 마찬가지로 스위치는 활성 디바이스가 해당 기능을 지원하는 경우에만 미리보기 창 상단에 표시됩니다.
여기에서는 해당 기능이 지원되는지 확인합니다:
property Camera cameraDevice property bool mIsFlashSupported: (cameraDevice && cameraDevice.active) ? cameraDevice.isFlashModeSupported(Camera.FlashOn) : false property bool mIsTorchSupported: (cameraDevice && cameraDevice.active) ? cameraDevice.isTorchModeSupported(Camera.TorchOn) : false
여기에서는 카메라 장치를 직접 제어하는 flashModeControl
스위치를 구현했습니다.
Switch { id: flashModeControl visible: flashControl.mIsFlashSupported opacity: checked ? 0.75 : 0.25 text: "Flash" contentItem: Text { text: flashModeControl.text color: "white" leftPadding: flashModeControl.indicator.width + flashModeControl.spacing } onPositionChanged: { if (position) { if (torchModeControl.checked) torchModeControl.toggle(); flashControl.cameraDevice.flashMode = Camera.FlashOn } else { flashControl.cameraDevice.flashMode = Camera.FlashOff } } }
토치 제어도 비슷한 방식으로 구현됩니다.
© 2025 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.