Auf dieser Seite

QML-Kamera-Anwendung

Diese auf „ Qt Quick “ basierende Anwendung zeigt, wie man mithilfe der API ein Standbild oder ein Video aufnimmt.

Kamera-App im Querformat mit Live-Vorschau und Aufnahmefunktionen

Dieses Beispiel veranschaulicht, wie man über QML auf Kamerafunktionen zugreift. Es zeigt, wie man Einstellungen ändert und Bilder oder Videos aufnimmt.

Ausführen des Beispiels

Sie können das Beispiel wie folgt ausführen:

Anwendungsstruktur

Der Großteil des QML-Codes in diesem Beispiel dient der Unterstützung der Benutzeroberfläche. Benutzerdefinierte Typen, die die Anforderungen erfüllen, wurden mithilfe bestehender „ Qt Quick “-Steuerelemente implementiert.

Auswahl des Layouts anhand der Bildschirmausrichtung

Die Logik für die Ausrichtung und den Layout-Zustand der Steuerelemente ist in einem separaten Item, controlLayout, wie folgt gekapselt:

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)
    }
}

Die Objekte „ stillControls “ und „ videoControls “ sind beide an die Eigenschaften „ state “ und „ buttonsWidth “ dieses „Item“-Objekts gebunden, wie in „ stillControls “ dargestellt:

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
}

Zur Unterstützung der Fehlersuche wird eine Meldung über die Änderung des Layout-Zustands protokolliert.

Hier ist das Hochformat-Layout:

Kamera-App im Hochformat mit Live-Vorschau und Aufnahmefunktionen

Sie können sehen, dass die Eigenschaft „ state “ anfangs auf „ PhotoCapture “ gesetzt ist.

Die „ states “ selbst sind dann wie folgt definiert:

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()
            }
        }
    }
]

Steuerelemente für die Aufzeichnung

Die Steuerelemente für die Aufzeichnung sind in „ PhotoCaptureControls.qml “ und „VideoCaptureControls.qml“ implementiert. Sie basieren jeweils auf einer „ FocusScope “, die die gemeinsamen Abmessungen und Ränder der Schaltflächen definiert, die von den Steuerelementen verwendet werden, und anschließend die Schaltflächen deklariert.

Dadurch wird auf der rechten Seite des Bildschirms eine Spalte erzeugt, die von oben nach unten die folgenden Steuerelemente enthält:

  • Eine Schaltfläche „ Capture “ oder „ Record “, die die Aufnahme startet.
  • Eine Schaltfläche „ capture properties “, die das Symbol des aktuell ausgewählten Weißabgleichmodus anzeigt und bei Betätigung in einem Popup-Fenster die Symbole der folgenden Optionen anzeigt:
    • Blitzmodus (falls verfügbar)
    • Weißabgleichsmodi
    • Belichtungskorrektur
  • Eine „ View “-Taste, sobald eine Aufnahme gemacht wurde.
  • Eine Schaltfläche, die das aktuell ausgewählte Aufnahmegerät anzeigt und bei Betätigung in einem Popup-Fenster eine Liste der verfügbaren Geräte zum Umschalten anzeigt.
  • Eine Schaltfläche „ Switch To “, die je nach aktuell aktiver Auswahl den alternativen Aufnahmemodus (Video oder Foto) anzeigt und bei Betätigung den Modus wechselt.
  • Eine Schaltfläche „ Quit “, die die Anwendung beendet.

Bedienfeld für die Fotoaufnahme

Bedienfeld für die Videoaufnahme

Bildaufnahme

Die Schaltfläche, die dies auslöst, ist in „CameraButton.qml“ definiert: Die Interaktion mit der Kamera erfolgt jedoch über die Steuerelementtypen. Sehen wir uns „PhotoCaptureControls“ an:

CameraButton {
    text: "Capture"
    implicitWidth: captureControls.buttonsWidth
    visible: captureControls.captureSession.imageCapture.readyForCapture
    onClicked: captureControls.captureSession.imageCapture.captureToFile("")
}

Zoom-Steuerelement

Der in „ ZoomControl.qml “ implementierte Typ „ZoomControl“ basiert auf einem „Item“ und erzeugt einen Schieberegler, der den Zoomfaktor darstellt und verschoben werden kann. Er verwendet eine exponentielle Berechnungsmethode, um den Zoomfaktor anhand der Position des „ grove “ zu ermitteln.

Der Balken ist nur sichtbar, wenn der Wert von `initialZoom` größer als 1 ist. Das bedeutet, dass die aktuell aktive Kamera über eine Zoomfunktion verfügt.

Leiste zur Einstellung der Zoomstufe

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
        }
    }
}

In „PhotoCaptureControls.qml“ und „VideoCaptureControls.qml“ setzt das Signal „ zoomTo “ die Eigenschaft „ zoomFactor “ der ausgewählten Kamera auf den berechneten Wert „ target “ und aktualisiert zudem den ZoomControl-Balken.

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
}

Blitz- und Taschenlampensteuerung

Zwischen Blitz- und Taschenlampenmodus umschalten

Dies ist in „ FlashControl.qml “ definiert und ermöglicht die Auswahl des Blitzmodus sowie das Umschalten der Taschenlampenfunktion über einen Schalter. Wie bei der Zoomsteuerung sind die Schalter nur dann im Vorschaufenster sichtbar, wenn das aktive Gerät diese Funktionen unterstützt.

Hier prüfen wir, ob die Funktionen unterstützt werden:

required property Camera camera

property bool mIsFlashSupported: camera.isFlashModeSupported(Camera.FlashOn)
property bool mIsTorchSupported: camera.isTorchModeSupported(Camera.TorchOn)

Hier implementieren wir den Schalter „ flashModeControl “, der auch das Kameragerät direkt steuert.

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
}

Die Taschenlampensteuerung wird auf ähnliche Weise implementiert.

Beispielprojekt @ code.qt.io

© 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.