Sur cette page

Application QML Camera

Cette application basée sur Qt Quick montre comment utiliser l'API pour capturer une image fixe ou une vidéo.

L'application Appareil photo en mode paysage montrant l'aperçu en direct et les commandes de capture

Cet exemple montre comment accéder aux fonctions de la caméra via QML. Il montre comment modifier les paramètres et capturer des images ou des vidéos.

Exécution de l'exemple

Pour exécuter l'exemple à partir de Qt Creatorouvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.

Structure de l'application

La majeure partie du code QML de cet exemple prend en charge l'interface utilisateur. Les types personnalisés qui répondent aux exigences ont été mis en œuvre à l'aide de contrôles Qt Quick existants.

Utilisation de l'orientation de l'écran pour sélectionner la disposition

La logique d'état de l'orientation et de la disposition des contrôles est encapsulée dans un élément distinct, controlLayout, comme suit :

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

Les objets stillControls et videoControls se lient tous deux aux propriétés state et buttonsWidth de cet élément, comme le montre stillControls:

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
}

Pour faciliter le débogage, un message concernant le changement d'état de la mise en page est enregistré.

Voici la mise en page du portrait :

L'application Appareil photo en mode portrait avec un aperçu en direct et des commandes de capture

Vous pouvez voir que la propriété state est initialement définie comme PhotoCapture.

Ensuite, les states sont définis comme suit :

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

Contrôles pour la capture

Les contrôles pour la capture sont mis en œuvre dans PhotoCaptureControls.qml et VideoCaptureControls.qml. Chacun d'eux est basé sur un site FocusScope qui définit les dimensions et les marges communes des boutons utilisés par les boutons de contrôle, puis déclare les boutons.

Cela génère une colonne sur le côté droit de l'écran qui comprend, de haut en bas, les contrôles suivants :

  • Un bouton Capture ou Record, qui lance la capture.
  • Un bouton capture properties qui affiche l'icône du mode de balance des blancs sélectionné et qui, lorsqu'il est enfoncé, utilise une fenêtre contextuelle pour afficher les icônes des options suivantes :
    • Mode flash (si disponible)
    • Modes de balance des blancs
    • Compensation de l'exposition
  • Un bouton View, une fois que quelque chose a été capturé.
  • Un bouton qui affiche le périphérique de capture actuellement sélectionné et qui, lorsqu'il est actionné, fournit une liste des périphériques disponibles vers lesquels basculer, à l'aide d'une fenêtre contextuelle.
  • Un bouton Switch To qui affiche le mode de capture alternatif (vidéo ou photo) en fonction de la sélection active actuelle et qui change de mode lorsqu'on appuie dessus.
  • Un bouton Quit, qui permet de quitter l'application.

Panneau de contrôle pour la capture de photos

Panneau de contrôle de la capture vidéo

Capture d'images

Le bouton qui déclenche cette opération est défini dans CameraButton.qml : mais son interaction avec l'appareil photo se trouve dans les types de contrôles, examinons PhotoCaptureControls :

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

Contrôle de zoom

Mis en œuvre à l'adresse ZoomControl.qml, le type ZoomControl est basé sur un élément et crée une barre représentant le niveau de zoom, qui peut également être déplacée. Il utilise une méthode de calcul exponentielle pour déterminer le facteur de zoom en fonction de la position de grove.

La barre n'est visible que si InitialZoom est supérieur à 1, ce qui signifie que l'appareil photo actuellement actif dispose d'une fonction de zoom.

Barre de niveau de zoom réglable

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

Dans PhotoCaptureControls.qml et VideoCaptureControls.qml, le signal zoomTo règle la propriété zoomFactor de la caméra sélectionnée sur la valeur calculée target et met à jour la barre 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
}

Contrôle du flash et de la torche

Basculer entre le mode Flash et le mode Torche

Défini à l'adresse FlashControl.qml, il permet de basculer la sélection du mode flash et la fonctionnalité de la torche via un commutateur. Comme pour le contrôle du zoom, les commutateurs ne sont visibles en haut de la fenêtre de prévisualisation que si l'appareil actif prend en charge ces fonctions.

Nous vérifions ici si les fonctions sont prises en charge :

required property Camera camera

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

Nous implémentons ici le commutateur flashModeControl, qui contrôle également directement le périphérique 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
}

Le contrôle de la torche est implémenté de la même manière.

Exemple de projet @ 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.