Qt5.14.2中使用QCamera实现切换相机、分辨率和图像捕获功能

2023-11-07

demo中主要涉及的Qt类有:相机类QCamera,取景器类QCameraViewfinder,图像捕获类QCameraImageCapture,因此添加模块multimedia multimediawidgets

QT += core gui multimedia multimediawidgets

widget.h中添加相关类声明:

class QCamera;
class QCameraViewfinder;
class QCameraImageCapture;
class QCameraInfo;
class QCameraViewfinderSettings;

在类Widget中添加私有变量:

QCamera *camera;                   //相机
QCameraViewfinder *viewfinder;     //取景器
QCameraImageCapture *imageCapture; //图像捕获
QList<QCameraInfo> cameras;        //相机列表
QList<QSize> mResSize = {};        //分辨率列表

widget.cpp中添加头文件:

#include <QCamera>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QFileDialog>
#include <QList>
#include <QDebug>

widget.cpp的构造函数中添加代码:

先设置下窗口名称及大小

setWindowTitle("Camera");
setFixedSize(600,400);

接着获取所有相机列表并选择一个相机初始化

cameras = QCameraInfo::availableCameras();   //获取所有相机的列表
//qDebug() << "this is camera: ";
if (cameras.count() > 0) {
    for(const QCameraInfo &cameraInfo:cameras) {
        qDebug() << cameraInfo.description();
    }
    camera = new QCamera(cameras.at(0));     //初始化实例化一个相机对象
}

实例化取景器类,取景器本质是一个窗口类,若不将当前窗口设为父对象,则可以另起一个窗口显示。将当前窗口设为父对象后,视频画面便在当前窗口显示。

//设置取景器
viewfinder = new QCameraViewfinder(this);
camera->setViewfinder(viewfinder);
viewfinder->resize(600,350);                 //设置取景器显示大小
//viewfinder->show();

实例化一个图像捕获类,并开启相机

imageCapture = new QCameraImageCapture(camera);
camera->start();                             //开启相机

设置默认摄像头的分辨率及帧率。注意:帧率一定要与摄像头匹配,否则不会显示画面。

//设置默认摄像头参数
QCameraViewfinderSettings set;
set.setResolution(640, 480);                 //设置显示分辨率
set.setMaximumFrameRate(25);                 //设置帧率
camera->setViewfinderSettings(set);

设置两个下拉框部件的初始化

//添加初始化的相机选项
for(const QCameraInfo &cameraInfo:cameras) {
    qDebug() << "CameraInfo:" << cameraInfo;
    ui->cameraSel->addItem(cameraInfo.description());
}
ui->cameraSel->setCurrentIndex(0);

//添加初始化相机的分辨率选项
mResSize = camera->supportedViewfinderResolutions();
//qDebug() << "mResSize = " << mResSize;
for (const QSize &msize:mResSize) {
       qDebug() << msize; //摄像头支持分辨率打印
       ui->resolutionSel->addItem(QString::number(msize.width(), 10) + "*" + QString::number(msize.height(), 10));
}
ui->resolutionSel->setCurrentIndex(0);

调整下widget.ui的内容,添加两个下拉框及一个按钮

在这里插入图片描述
编写信号槽连接

首先是选择摄影机,先释放之前的内存,再将camera指向新的。选择新的相机意味着分辨率选项也会变化,因此需要删除分辨率下拉框中前相机的所有分辨率选项,再添加新相机的所有分辨率选项。

connect(ui->cameraSel, QOverload<int>::of(&QComboBox::activated), [=](int index){
    //qDebug() << "Index" << ui->cameraSel->currentIndex() << ": " << ui->cameraSel->currentText();
    camera->stop();
    delete camera;
    camera = new QCamera(cameras[index]);                //camera指向指定的摄像头
    camera->setCaptureMode(QCamera::CaptureStillImage);  //设定捕获模式
    camera->setViewfinder(viewfinder);                   //设置取景器
    camera->start();

    //删除前相机的所有分辨率内容
    for (int i = 0; i < mResSize.size(); i++) {
           ui->resolutionSel->removeItem(0);
    }

    //添加新相机的所有分辨率
    mResSize.clear();
    //qDebug() << "now mResSize = " << mResSize;
    mResSize = camera->supportedViewfinderResolutions();
    for (const QSize &msize:mResSize) {
           qDebug() << msize; //摄像头支持分辨率打印
           ui->resolutionSel->addItem(QString::number(msize.width(), 10) + "*" + QString::number(msize.height(), 10));
    }
    ui->resolutionSel->setCurrentIndex(0);
});

选择分辨率

connect(ui->resolutionSel, QOverload<int>::of(&QComboBox::activated), [=](int index){
    //qDebug() << "Index" << ui->resolutionSel->currentIndex() << ": " << ui->resolutionSel->currentText();
    //qDebug() << "mResSize:" << mResSize[index];
    //重新设置摄像头参数
    QCameraViewfinderSettings reset;
    reset.setResolution(mResSize[index]);
    camera->setViewfinderSettings(reset);
});

截图按钮

connect(ui->screenShot, &QPushButton::clicked, [=](){
    camera->setCaptureMode(QCamera::CaptureStillImage);
    delete imageCapture;
    imageCapture = new QCameraImageCapture(camera);
    QString fileName = QFileDialog::getSaveFileName();
    camera->searchAndLock();
    imageCapture->capture(fileName);
    camera->unlock();
});

最终效果

在这里插入图片描述
附完整代码

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class QCamera;
class QCameraViewfinder;
class QCameraImageCapture;
class QCameraInfo;
class QCameraViewfinderSettings;

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    QCamera *camera;                   //相机
    QCameraViewfinder *viewfinder;     //取景器
    QCameraImageCapture *imageCapture; //图像捕获
    QList<QCameraInfo> cameras;        //相机列表
    QList<QSize> mResSize = {};        //分辨率列表
    //QCameraViewfinderSettings *set;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QCamera>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QFileDialog>
#include <QList>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("Camera");
    setFixedSize(600,400);

    cameras = QCameraInfo::availableCameras();   //获取所有相机的列表
    //qDebug() << "this is camera: ";
    if (cameras.count() > 0) {
        for(const QCameraInfo &cameraInfo:cameras) {
            qDebug() << cameraInfo.description();
        }
        camera = new QCamera(cameras.at(0));     //初始化实例化一个相机对象
    }

    //设置取景器
    viewfinder = new QCameraViewfinder(this);
    camera->setViewfinder(viewfinder);
    viewfinder->resize(600,350);                 //设置取景器显示大小
    //viewfinder->show();

    imageCapture = new QCameraImageCapture(camera);
    camera->start();                             //开启相机

    //设置默认摄像头参数
    QCameraViewfinderSettings set;
    set.setResolution(640, 480);                 //设置显示分辨率
    set.setMaximumFrameRate(25);                 //设置帧率
    camera->setViewfinderSettings(set);

    //添加初始化的相机选项
    for(const QCameraInfo &cameraInfo:cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
        ui->cameraSel->addItem(cameraInfo.description());
    }
    ui->cameraSel->setCurrentIndex(0);

    //添加初始化相机的分辨率选项
    mResSize = camera->supportedViewfinderResolutions();
    //qDebug() << "mResSize = " << mResSize;
    for (const QSize &msize:mResSize) {
           qDebug() << msize; //摄像头支持分辨率打印
           ui->resolutionSel->addItem(QString::number(msize.width(), 10) + "*" + QString::number(msize.height(), 10));
    }
    ui->resolutionSel->setCurrentIndex(0);

    //信号槽连接
    connect(ui->cameraSel, QOverload<int>::of(&QComboBox::activated), [=](int index){
        //qDebug() << "Index" << ui->cameraSel->currentIndex() << ": " << ui->cameraSel->currentText();
        camera->stop();
        delete camera;
        camera = new QCamera(cameras[index]);                //camera指向指定的摄像头
        camera->setCaptureMode(QCamera::CaptureStillImage);  //设定捕获模式
        camera->setViewfinder(viewfinder);                   //设置取景器
        camera->start();

        //删除前相机的所有分辨率内容
        for (int i = 0; i < mResSize.size(); i++) {
               ui->resolutionSel->removeItem(0);
        }

        //添加新相机的所有分辨率
        mResSize.clear();
        //qDebug() << "now mResSize = " << mResSize;
        mResSize = camera->supportedViewfinderResolutions();
        for (const QSize &msize:mResSize) {
               qDebug() << msize; //摄像头支持分辨率打印
               ui->resolutionSel->addItem(QString::number(msize.width(), 10) + "*" + QString::number(msize.height(), 10));
        }
        ui->resolutionSel->setCurrentIndex(0);
    });

    connect(ui->resolutionSel, QOverload<int>::of(&QComboBox::activated), [=](int index){
        //qDebug() << "Index" << ui->resolutionSel->currentIndex() << ": " << ui->resolutionSel->currentText();
        //qDebug() << "mResSize:" << mResSize[index];
        //重新设置摄像头参数
        QCameraViewfinderSettings reset;
        reset.setResolution(mResSize[index]);
        camera->setViewfinderSettings(reset);
    });

    connect(ui->screenShot, &QPushButton::clicked, [=](){
        camera->setCaptureMode(QCamera::CaptureStillImage);
        delete imageCapture;
        imageCapture = new QCameraImageCapture(camera);
        QString fileName = QFileDialog::getSaveFileName();
        camera->searchAndLock();
        imageCapture->capture(fileName);
        camera->unlock();
    });
}

Widget::~Widget()
{
    delete ui;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt5.14.2中使用QCamera实现切换相机、分辨率和图像捕获功能 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • C++ 中的双精度型数字

    尽管内部表示有 17 位 但 IEE754 64 位 浮点应该正确表示 15 位有效数字 有没有办法强制第 16 位和第 17 位为零 Ref http msdn microsoft com en us library system dou
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 我可以在“字节数”设置为零的情况下调用 memcpy() 和 memmove() 吗?

    当我实际上没有什么可以移动 复制的时候 我是否需要处理这些情况memmove memcpy 作为边缘情况 int numberOfBytes if numberOfBytes 0 memmove dest source numberOfBy

随机推荐

  • 【Pandas学习】读、存excel数据

    目录 一 读数据 二 将df存为excel 1 pandas DataFrame to csv 函数语法 2 利用 import os 获取保存路径 3 产生新的数据 添加至上述csv文件中已有数据的后面 4 多sheet 指定存入的she
  • Leecode 每日一题 problem2 (03-23)

    给你两个 非空 的链表 表示两个非负的整数 它们每位数字都是按照 逆序 的方式存储的 并且每个节点只能存储 一位 数字 请你将两个数相加 并以相同形式返回一个表示和的链表 你可以假设除了数字 0 之外 这两个数都不会以 0 开头 来源 力扣
  • 2021-10-24

    Python 简介 Python 是一个高层次的结合了解释性 编译性 互动性和面向对象的脚本语言 Python 的设计具有很强的可读性 相比其他语言经常使用英文关键字 其他语言的一些标点符号 它具有比其他语言更有特色语法结构 Python
  • ERR_PNPM_NO_GLOBAL_BIN_DIR Unable to find the global bin directory

    错误提示 ERROR Unable to find the global bin directory Run pnpm setup to create it automatically or set the global bin dir s
  • (1)minikube玩转k8s集群之虚拟机支持嵌套虚拟化

    配套视频教程 1 Minikube介绍 简单说 创建k8s集群很麻烦 minikube可以让我们快速搭建一个k8s集群用于学习 Minikube 是一种可以让您在本地轻松运行 Kubernetes 的工具 Minikube 在笔记本电脑上的
  • openId和unionId的区别

    网友的解释 微信的用户隐私策略 每个接入微信的应用 公众号 APP 就像一个独立的商场 用户使用这些应用就像逛商场 商场用会员卡识别用户 类似的 我们根据商场名字为每个用户生成了一张专属会员卡 openid 每张会员卡只能在对应的商场才能够
  • Navicat for MySQL安装教程

    Navicat for MySQL是一款强大的 MySQL 数据库管理和开发工具 它为专业开发者提供了一套强大的足够尖端的工具 但对于新用户仍然易于学习 Navicat for MySQL 基于Windows平台 为 MySQL 量身订作
  • R语言logistic回归的细节解读

    本文首发于公众号 医学和生信笔记 完美观看体验请至公众号查看本文 医学和生信笔记 专注R语言在临床医学中的使用 R语言数据分析和可视化 文章目录 二项logistic回归 R语言中的 factor 函数可以把变量变为因子类型 默认是没有等级
  • Redis缓存击穿问题及解决思路

    一 什么是缓存击穿 缓存击穿问题也叫热点Key问题 就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了 无数的请求访问会在瞬间给数据库带来巨大的冲击 逻辑分析 假设线程1在查询缓存之后 本来应该去查询数据库 然后把这个数据重新加载
  • 【Java】对象的序列化与反序列化

    对象序列化的含义 对象序列化 Serialize 指将一个Java对象写入IO流中 对象的反序列化 Deserialize 则是指从IO流中恢复该Java对象 如果想让某个Java对象能够序列化 则必须让它的类实现java io Seria
  • 使用docker需要知道的基础知识

    一 docker概念 1 1 docker仓库 镜像 容器的作用和三者之间的关系是什么 答 Docker 仓库 用来保存镜像 可以理解为代码控制中的代码仓库 Docker 镜像 是用于创建 Docker 容器的模板 Docker 容器 是独
  • 前端工程化详解——理解与实践前端工程化

    前言 前端工程化一直是一个老生常谈的问题 不管是面试还是我们在公司做基建都会经常提到前端工程化 那么为什么经常会说到前端工程化 并没有听过后端工程化 Java工程化或者Python工程化呢 我们理解的前端工程化是不是一直都是Webpack的
  • 回望2001年的雪鸟城:引发全球软件革命的“敏捷宣言”是如何诞生的?

    将人们置于流程之上 专注于开发可以工作的软件 而不是软件的文档 和你的客户一起工作 而不是为一份合同而争吵 在此过程中 要对改变持开放态度 编者按 敏捷 Agile 这个对于开发真来说不在陌生的概念 已经提出了近17年了 其背后的哲学理念也
  • [CSDN竞赛]第五期参赛回顾

    CSDN竞赛 第五期参赛回顾 体验感想 第一次参加 本来有点小期待 那天还起晚了 结果登录不上去 发现大家都有问题 对我来说反而是好事 本来早上没有下午晚上更加精神 下面是提的建议 上次的登录问题 希望官方下次不要再出现 一定要准备充足 为
  • Unity Shader:用几何着色器实现复联3灭霸的终极大招灰飞烟灭

    图1 正常渲染 图2 几何着色器粒子化特效进行中 图3 几何着色器粒子化特效进行中 1 用几何着色器进行图元转换 在OpenGL渲染管线中 几何着色器Geometry Shader有一个独一无二的功能 既是图元转换 可简单理解为对基本图元点
  • 微信小程序默认下拉刷新和自定义下拉刷新的方式

    1 默认下拉刷新 在指定页面对应的 json配置文件中加入 enablePullDownRefresh true backgroundTextStyle dark 在对应的 js文件中 写入onPullDownRefresh 如果存在则替换
  • 手把手教你做一套“能源管理系统” A

    hello 大家好 我是CC 今天让CC来手把手教大家设计一套 能源管理系统 上个视频咱们有说到 能源管理系统 的范围很广 可以粗分为面向供给侧和面向消费侧 其中面向消费侧又可以分为 家庭能源管理系统HEMS 社区 园区能源管理系统CEMS
  • EQ频响曲线绘制和DRC特性曲线绘制

    目录 1 EQ 系数计算和频响曲线绘制 1 1 基本流程 1 2 EQ参数输入 1 3 滤波器系数计算 1 4 频率响应计算 1 5 曲线绘制 2 DRC特性曲线绘制 2 1 基本流程 2 2 参数输入 2 3 增益计算 2 4 静态特性曲
  • Java学习书籍推荐(步步为营)

    概述 本文只要介绍 Java学习的书籍 进阶之路 始于行动 编程重在理解加多实践 在当今快速发展的时代 要学会站在巨人的肩膀上 吸取经验 看书就是最快与最低成本的进阶之路 史上没有最好的书籍 只有适合自己的书籍 小伙伴们开始行动吧 Java
  • Qt5.14.2中使用QCamera实现切换相机、分辨率和图像捕获功能

    demo中主要涉及的Qt类有 相机类QCamera 取景器类QCameraViewfinder 图像捕获类QCameraImageCapture 因此添加模块multimedia multimediawidgets QT core gui