Qt软件开发-摄像头检测使用软件V1.1

系列文章目录

Qt软件开发-摄像头检测使用软件V1.1


文章目录


前言

之前,在Qt软件开发-摄像头检测使用软件:https://blog.csdn.net/xuming2044/article/details/145054460?spm=1011.2415.3001.5331,实现了一个简单的本地摄像头检测和使用软件,由于功能比较单一,只能实现两个功能:1、本地摄像头的检测、2、摄像头的使用。于是在此基础上,有了Qt软件开发-摄像头检测使用软件V1.1。


一、V1.1增加了哪些功能?

  1. 拍照功能:对当前画面进行拍照并保存到指定目录下;
  2. 录像功能:对当前正在显示的摄像头画面进行录屏,并以视频文件的形式保存到本地指定目录下;

二、代码构成

1.总体结构

2. 代码内容

main.cpp:

cpp 复制代码
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp:

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    cameras = QMediaDevices::videoInputs();//这里会返回所有可用的摄像头
    //qDebug() << "cameras.size:" <<cameras.size();
    for (const QCameraDevice &cameraDevice : cameras) {//将摄像头列表的描述的信息显示到lw_cameras
        ui->lw_cameras->addItem(cameraDevice.description());
    }

    //cam = new QCamera(QMediaDevices::defaultVideoInput());//使用默认的集成摄像头
    //QCamera defCamera(QCameraDevice());
    //cap = new QMediaCaptureSession(this);
    //cap->setCamera(cam);

    cap.setVideoOutput(ui->video_widget);//显示画面到videoWidget

    image_cap.setFileFormat(QImageCapture::JPEG);//设置拍照保存的格式
    image_cap.setQuality(QImageCapture::VeryHighQuality);//设置拍照的质量
    cap.setImageCapture(&image_cap);//设置保存图像的对象

    media_format.setFileFormat(QMediaFormat::AVI);//设置视频的文件格式
   // media_format.setAudioCodec(QMediaFormat::AudioCodec::MP3);//设置音频编解码
   // media_format.setVideoCodec(QMediaFormat::VideoCodec::MPEG2);//设置视频编解码
    video_recorder.setMediaFormat(media_format);//初始化设置文件格式信息
    video_recorder.setQuality(QMediaRecorder::VeryHighQuality);//设置视频的质量为超高质量
    cap.setRecorder(&video_recorder);//设置保存录制视频的对象
    timer.setInterval(1000);//定时器每一秒触发超时
    mm = 0;
    ss = 0;//视频录制持续时间初始化为0

    image_path = "C:/Users/chang/Desktop/"; //保存照片的目录
    video_path = "C:/Users/chang/Desktop/"; //保存视频的目录

    //connect(&cap,SIGNAL(imageCaptureChanged()),this,SLOT(on_imageCaptureChanged()));//收到拍屏成功的信号之后保存图片到本地
    //connect(&cap,SIGNAL(screenCaptureChanged()),this,SLOT(on_screenCaptureChanged()));
    connect(&image_cap,SIGNAL(imageSaved(int,QString)),this,SLOT(on_imageSaved(int,QString)));//收到保存图片成功的信号之后显示到lb_imagecap
    connect(&video_recorder,SIGNAL(errorOccured(QMediaRecorder::Error,QString)),this,SLOT(on_errorOccured(QMediaRecorder::Error,QString)));
    connect(&timer,SIGNAL(timeout()),this,SLOT(on_timeout()));//每秒触发超时,然后更新已录制视频的时间
    connect(&video_recorder,SIGNAL(recorderStateChanged(QMediaRecorder::RecorderState)),this,SLOT(on_recorderStateChanged(QMediaRecorder::RecorderState)));//根据recorder的实际状态进行相应操作
    //qDebug() << 0.1;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pb_display_clicked()//显示lw_cameras当前选择的摄像头画面到QVideoWidget
{
    for (const QCameraDevice &cameraDevice : cameras) {
        if(cameraDevice.description() == ui->lw_cameras->currentItem()->text()){
            cam.setCameraDevice(cameraDevice);
            cap.setCamera(&cam);
        }
    }
    cam.start();//启动摄像头
    //cap->camera()->activeChanged(true);
    //qDebug() << "cap->camera()->cameraDevice().position():" << cap->camera()->isAvailable();
    //qDebug() << "cap->camera()->cameraDevice().position():" << cap->camera()->cameraDevice().position();

    if(!cap.camera()->isActive()){
       // qDebug() << 2;
        cap.camera()->setActive(1);
    }
}


void MainWindow::on_pb_stopDisplay_clicked()//停止显示摄像头画面到QVideoWidget
{
    cam.stop();//关闭摄像头
}


void MainWindow::on_pb_quit_clicked()//退出软件
{
    close();
}


void MainWindow::on_lw_cameras_itemClicked(QListWidgetItem *item)//单机选中当前项目
{
    ui->lw_cameras->setCurrentItem(item);
}


void MainWindow::on_lw_cameras_itemDoubleClicked(QListWidgetItem *item)//双击直接开启选中摄像头并显示画面
{
    ui->lw_cameras->setCurrentItem(item);
    on_pb_display_clicked();
}

void MainWindow::on_pb_imagecap_clicked()//拍照
{
    //cap.imageCapture();
    QString file_name = image_path + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
    qDebug() << file_name;

    if(image_cap.isReadyForCapture())
    {
        image_cap.captureToFile(file_name);
    }
    else
    {
        ui->lb_imagecap->setText("Image Capture is not for capture");
    }
}

void MainWindow::on_imageSaved(int id, const QString &fileName)
{
    if(id != -1)
    {
        ui->lb_imagecap->setText(QString("文件保存成功,文件ID:%1,文件名:%2").arg(id).arg(fileName));
    }
    else
    {
        ui->lb_imagecap->setText(QString("文件保存失败,文件ID:%1,文件名:%2").arg(id).arg(fileName));
    }
}

void MainWindow::on_pb_videocap_clicked()//开始、停止录像
{

    if(video_recorder.recorderState() == QMediaRecorder::StoppedState)
    {
        QString file_dst = video_path + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
        video_recorder.setOutputLocation(QUrl::fromLocalFile(file_dst));
        //QUrl file_dst(video_path + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
        //video_recorder.setOutputLocation(file_dst);
        qDebug() << QUrl::fromLocalFile(file_dst);
        video_recorder.record();
    }
    else if(video_recorder.recorderState() == QMediaRecorder::RecordingState)
    {
        video_recorder.stop();
    }
    else if(video_recorder.recorderState() == QMediaRecorder::PausedState)
    {
        //未实现状态
    }
}

void MainWindow::on_errorOccured(QMediaRecorder::Error error, const QString &errorString)
{
    QMessageBox::critical(this,"错误",QString("errorValue:%1\nerrorString:%2").arg(error).arg(errorString));
}

void MainWindow::on_recorderStateChanged(QMediaRecorder::RecorderState state)
{
    if(state == QMediaRecorder::RecordingState)
    {
        QString time = QString("%1:%2").arg(mm,2,10,QChar('0')).arg(ss,2,10,QChar('0'));//将每个数字转换为格式:(值,宽度,进制,填充符号)
        ui->lb_videocap->setText(time);//显示开始录制的时间
        timer.start();//启动定时器
        ui->pb_videocap->setText("停止录像");
    }
    else if(state == QMediaRecorder::StoppedState)
    {
        timer.stop();//关闭定时器
        mm = 0;
        ss = 0;//录制完后时间清零,为下次录制时间做准备
        ui->pb_videocap->setText("开始录像");
    }
    else if(state == QMediaRecorder::PausedState)
    {
        //...
    }
}

void MainWindow::on_timeout()//每秒被定时器信号触发,更新已录制的时间
{
    if(++ss == 60)//秒先加一
    {
        ss = 0;
        mm++;
    }

    QString time = QString("%1:%2").arg(mm,2,10,QChar('0')).arg(ss,2,10,QChar('0'));//将每个数字转换为格式:(值,宽度,进制,填充符号)
    ui->lb_videocap->setText(time);//显示开始录制的时间
}

三、效果展示图

  1. 拍照:

  2. 录屏:

总结

  1. V1.1版本是对最初版本的功能添加,V1.1和windows系统自带相机软件唯一的区别:windows相机似乎只能使用电脑自带的摄像头,而V1.1可以任意选择所有通过USB连接到电脑上的摄像头;
  2. 该版本录制的视频未实现收音的功能,只有纯画面展示,如有需求可自行研究;
  3. 下一个版本可以考虑将摄像头画面实时推流到远程主机上,并实现由远端用户来选择查看哪个摄像头的画面。
相关推荐
董先生_ad986ad1 小时前
C# 中的 `lock` 关键字本质
开发语言·c#
元亓亓亓2 小时前
Java后端开发day36--源码解析:HashMap
java·开发语言·数据结构
道剑剑非道2 小时前
QT 打包安装程序【windeployqt.exe】报错c000007d原因:Conda巨坑
开发语言·qt·conda
小邓儿◑.◑2 小时前
C++武功秘籍 | 入门知识点
开发语言·c++
码银4 小时前
Java 集合:泛型、Set 集合及其实现类详解
java·开发语言
大G哥4 小时前
PHP标签+注释+html混写+变量
android·开发语言·前端·html·php
傻啦嘿哟4 小时前
HTTP代理基础:网络新手的入门指南
开发语言·php
fish_study_csdn4 小时前
pytest 技术总结
开发语言·python·pytest
杨筱毅5 小时前
【优秀三方库研读】【C++基础知识】odygrd/quill -- 折叠表达式
c++·三方库研读
曹牧5 小时前
Java 调用webservice接口输出xml自动转义
java·开发语言·javascript