摄像头示例

展示如何捕捉静态图片或录制视频。

摄像头示例演示了如何使用 Qt 多媒体实现一些基本的摄像头功能,以捕捉静态图片和录制带音频的视频片段。

运行示例

要从 Qt Creator 中运行示例,请打开“欢迎”模式并从“示例”中选择示例。有关更多信息,请访问构建和运行示例

示例实现了一个 Camera 类,该类充当我们的摄像头接口。它具有用户界面,控制函数,设置值以及定义图片或视频片段保存位置的方式。它还将存储图片和视频设置。

摄像头类使用

  • QCamera 的实例,该实例是访问硬件的 API 类界面。
  • QImageCapture 的实例来捕捉静态图片。
  • QMediaRecorder 的实例来录制视频。它还包含用户界面对象。

摄像头的构造函数

摄像头构造函数对用户界面进行了基本初始化,包括默认禁用所有按钮。

Camera::Camera() : ui(new Ui::Camera)
{
    ui->setupUi(this);
    // disable all buttons by default
    updateCameraActive(false);
    readyForCapture(false);
    ui->recordButton->setEnabled(false);
    ui->pauseButton->setEnabled(false);
    ui->stopButton->setEnabled(false);
    ui->metaDataButton->setEnabled(false);

它请求访问输入设备的权限

#if QT_CONFIG(permissions)
    // camera
    QCameraPermission cameraPermission;
    switch (qApp->checkPermission(cameraPermission)) {
    case Qt::PermissionStatus::Undetermined:
        qApp->requestPermission(cameraPermission, this, &Camera::init);
        return;
    case Qt::PermissionStatus::Denied:
        qWarning("Camera permission is not granted!");
        return;
    case Qt::PermissionStatus::Granted:
        break;
    }
    // microphone
    QMicrophonePermission microphonePermission;
    switch (qApp->checkPermission(microphonePermission)) {
    case Qt::PermissionStatus::Undetermined:
        qApp->requestPermission(microphonePermission, this, &Camera::init);
        return;
    case Qt::PermissionStatus::Denied:
        qWarning("Microphone permission is not granted!");
        return;
    case Qt::PermissionStatus::Granted:
        break;
    }
#endif

输入被分配

    m_audioInput.reset(new QAudioInput);
    m_captureSession.setAudioInput(m_audioInput.get());

    // Camera devices:

    videoDevicesGroup = new QActionGroup(this);
    videoDevicesGroup->setExclusive(true);
    updateCameras();

将 UI 信号连接到响应触发事件的槽

    connect(&m_devices, &QMediaDevices::videoInputsChanged, this, &Camera::updateCameras);

    connect(videoDevicesGroup, &QActionGroup::triggered, this, &Camera::updateCameraDevice);
    connect(ui->captureWidget, &QTabWidget::currentChanged, this, &Camera::updateCaptureMode);

    connect(ui->metaDataButton, &QPushButton::clicked, this, &Camera::showMetaDataDialog);
    connect(ui->exposureCompensation, &QAbstractSlider::valueChanged, this,
            &Camera::setExposureCompensation);

    setCamera(QMediaDevices::defaultVideoInput());

然而,大部分工作是在调用setCamera() 函数时完成的,此时传入一个 QCameraDevice

setCamera()

setCamera() 使用信号和槽在用户界面和摄像头类的功能之间设置各种连接。它还实例化并初始化了 QCameraQImageCaptureQMediaRecorder 对象。

void Camera::setCamera(const QCameraDevice &cameraDevice)
{
    m_camera.reset(new QCamera(cameraDevice));
    m_captureSession.setCamera(m_camera.data());

    connect(m_camera.data(), &QCamera::activeChanged, this, &Camera::updateCameraActive);
    connect(m_camera.data(), &QCamera::errorOccurred, this, &Camera::displayCameraError);

    if (!m_mediaRecorder) {
        m_mediaRecorder.reset(new QMediaRecorder);
        m_captureSession.setRecorder(m_mediaRecorder.data());
        connect(m_mediaRecorder.data(), &QMediaRecorder::recorderStateChanged, this,
                &Camera::updateRecorderState);
        connect(m_mediaRecorder.data(), &QMediaRecorder::durationChanged, this,
                &Camera::updateRecordTime);
        connect(m_mediaRecorder.data(), &QMediaRecorder::errorChanged, this,
                &Camera::displayRecorderError);
    }

    if (!m_imageCapture) {
        m_imageCapture.reset(new QImageCapture);
        m_captureSession.setImageCapture(m_imageCapture.get());
        connect(m_imageCapture.get(), &QImageCapture::readyForCaptureChanged, this,
                &Camera::readyForCapture);
        connect(m_imageCapture.get(), &QImageCapture::imageCaptured, this,
                &Camera::processCapturedImage);
        connect(m_imageCapture.get(), &QImageCapture::imageSaved, this, &Camera::imageSaved);
        connect(m_imageCapture.get(), &QImageCapture::errorOccurred, this,
                &Camera::displayCaptureError);
    }

启用静态和视频录制视觉选项卡

    m_captureSession.setVideoOutput(ui->viewfinder);

    updateCameraActive(m_camera->isActive());
    updateRecorderState(m_mediaRecorder->recorderState());
    readyForCapture(m_imageCapture->isReadyForCapture());

    updateCaptureMode();

最后调用 QCamera 对象的 start() 函数。

    m_camera->start();

触发捕捉

摄像头已准备好响应用户命令,现在它等待一个适合的事件。这样一个事件可以是应用程序窗口上的 Qt::Key_CameraFocusQt::Key_Camera 按键的按键。

Qt::Key_CameraFocus 仅仅显示预览并锁定摄像头设置。

}

void Camera::keyPressEvent(QKeyEvent *event)
{
    if (event->isAutoRepeat())
        return;

    switch (event->key()) {
    case Qt::Key_CameraFocus:
        displayViewfinder();
        event->accept();
        break;

Qt::Key_Camera 将在执行图片捕捉时调用 takeImage(),或在录制视频时调用 QMediaRecorder 实例上的 record()stop()(如果已经在录制的话)。

    case Qt::Key_Camera:
        if (m_doImageCapture) {
            takeImage();
        } else {
            if (m_mediaRecorder->recorderState() == QMediaRecorder::RecordingState)
                stop();
            else
                record();
        }
        event->accept();
        break;

示例项目 @ code.qt.io

© 2024 The Qt Company Ltd. 以下文档中包含的文档贡献均为各自所有者的版权。本提供的文档根据自由软件基金会发布的GNU自由文档许可证1.3版本的条款进行许可。Qt及其相关标志是The Qt Company Ltd.在芬兰和其他国家/地区的商标。商标所有权归其相应所有者。