1.QCamera
.h文件
#include <QtWidgets/QMainWindow>
#include "ui_QCamera_test1.h"
#include <QCamera>
#include <QtMultimedia>
#include <QtMultimediaWidgets>
#include<QMediaCaptureSession>
#include <QMediaDevices>
#include <QImageCapture>//拍照
class QCamera_test1 : public QMainWindow
{
Q_OBJECT
public:
QCamera_test1(QWidget* parent = nullptr);
~QCamera_test1();
private:
Ui::QCamera_test1Class ui;
QCamera* _camera;
QMediaCaptureSession* _captureSession;
//智能指针
QScopedPointer<QImageCapture> imageCapture;//拍照
public slots:
void btn_sopen_clicked();
void btn_ssave_clicked();
void processCapturedImage(int requestId, const QImage& img);
public:
//显示拍照的图像在当前第0个画布
void displayImage();
void displayCapturedImage();
};
.cpp代码
#include "QCamera_test1.h"
#include <QDateTime>
QCamera_test1::QCamera_test1(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//信号与槽点击打开相机按钮
connect(ui.btn_open, &QPushButton::clicked, this, &QCamera_test1::btn_sopen_clicked);
//信号与槽点击保存相机按钮
connect(ui.btn_save, &QPushButton::clicked, this, &QCamera_test1::btn_ssave_clicked);
//初始化相机和捕获会话
this->_camera = new QCamera(QMediaDevices::defaultVideoInput());
this->_captureSession = new QMediaCaptureSession();
//拍照功能,QImageCapture 类是一个高级图像录制类。它不是单独使用的,而是用于访问其他媒体对象的媒体录制功能
this->imageCapture.reset(new QImageCapture);
//imageCapture对象(通过get()方法获取原始指针)设置为mediaCaptureSession对象的图像捕捉设备
this->_captureSession->setImageCapture(this->imageCapture.get());
//连接信号和槽当图像被捕捉到时,imageCaptured信号会被触发,并调用processCapturedImage方法。
connect(this->imageCapture.get(), &QImageCapture::imageCaptured, this, &QCamera_test1::processCapturedImage);
// 获取系统上可用的视频输入设备列表存入QList列表中。
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
//for循环,遍历所有摄像头
for (const QCameraDevice& cameraDevice : cameras) {
//打印摄像头信息
qDebug() << cameraDevice.description();
//创建摄像头对象,把遍历的摄像头设备放入摄像头对象中(只有一个摄像头的时候)把遍历的cameraDevice放入摄像头对象中_camera
//设置摄像头设备,捕获会话视频输出以及摄像头。
this->_camera->setCameraDevice(cameraDevice);
//设置捕获会话视频输出
this->_captureSession->setCamera(this->_camera);
//把camera图像放入ui中;
this->_captureSession->setVideoOutput(ui.videowidget);
}
如果列表不为空,初始化相机和捕获会话
//if (!cameras.isEmpty()) {
// // 假设我们选择第一个摄像头(可以自己来决定)
// QCameraDevice selectedCamera = cameras.first();
// // 初始化相机对象,并设置选定的摄像头设备
// this->_camera = new QCamera(selectedCamera);
// // 初始化捕获会话对象,并设置相机和视频输出 ,把第一个相机放入媒体捕捉器中
// this->_captureSession->setCamera(this->_camera);
// //把camera图像放入ui中,在ui中显示。(选一个QWidget形状然后提升为QVideoWidget)
// this->_captureSession->setVideoOutput(ui.videowidget);
// // 开始捕获会话(如果需要的话)
// // this->_captureSession->start();
//}
//else {
// // 处理没有可用摄像头的情况
// qDebug() << "No cameras available.";
//}
}
QCamera_test1::~QCamera_test1()
{}
//打开摄像头
void QCamera_test1::btn_sopen_clicked()
{
_camera->start();
}
void QCamera_test1::processCapturedImage(int requestId, const QImage& img) {
Q_UNUSED(requestId);
QImage scaledImage = img.scaled(ui.videowidget->size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
//显示当前图像,4秒之后不再显示,默认保存到系统相册路径下
ui.viewfinder->setPixmap(QPixmap::fromImage(scaledImage));
QTimer::singleShot(4000, this, &QCamera_test1::displayImage);
displayCapturedImage();
}
//显示拍照的图像在当前第0个画布
void QCamera_test1::displayImage() {
ui.stackedWidget->setCurrentIndex(0);
}
void QCamera_test1::displayCapturedImage() {
ui.stackedWidget->setCurrentIndex(1);
}
//保存图片
void QCamera_test1::btn_ssave_clicked() {
// 获取桌面路径
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
//获取当前时间
QDateTime currentDataTime = QDateTime::currentDateTime();
QString time = currentDataTime.toString("yyyyMMdd_hhmmss");
// 构建完整的文件路径,这里使用了一个简单的文件名,你可以根据需要更改
QString filePath = desktopPath + "/captured_image" + time + ".jpg";
// 调用 captureToFile 方法保存图片到指定路径
this->imageCapture->captureToFile(filePath);
QMessageBox::information(this, "提示", "保存成功");
}
ui文件
2.QCamera
2.1加入分辨率与帧率的显示与获取
.h文件
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QCamera_test1.h"
#include <QCamera>
#include <QtMultimedia>
#include <QtMultimediaWidgets>
#include<QMediaCaptureSession>
#include <QMediaDevices>
#include <QImageCapture>//拍照
#include <QVideoSink>//获取分辨率
#include <QCameraDevice>//设置分辨率与帧率
class QCamera_test1 : public QMainWindow
{
Q_OBJECT
public:
QCamera_test1(QWidget* parent = nullptr);
~QCamera_test1();
private:
Ui::QCamera_test1Class ui;
QCamera* _camera;
QMediaCaptureSession* _captureSession;
QScopedPointer<QImageCapture> imageCapture;//拍照
//QCameraDevice* cameraDevice;//摄像头设备
QSize _resolution;//分辨率
QSize _frameRate;//帧率
QVideoSink* sink;
int currentFrameRate; // 新增成员变量来存储当前帧率
public slots:
void btn_sopen_clicked();
void btn_ssave_clicked();
void processCapturedImage(int requestId, const QImage& img);
void btn_setfenbianlv_clicked();
void onFrameChanged(const QVideoFrame& frame);
public:
//显示拍照的图像在当前第0个画布
void displayImage();
void displayCapturedImage();
void setCameraResolutionAndFrameRate(const QSize& resolution, int frameRate);
};
.cpp文件
#include "QCamera_test1.h"
#include <QDateTime>
QCamera_test1::QCamera_test1(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//信号与槽点击打开相机按钮
connect(ui.btn_open, &QPushButton::clicked, this, &QCamera_test1::btn_sopen_clicked);
//信号与槽点击保存相机按钮
connect(ui.btn_save, &QPushButton::clicked, this, &QCamera_test1::btn_ssave_clicked);
connect(ui.btn_set_fenbianlv, &QPushButton::clicked, this, &QCamera_test1::btn_setfenbianlv_clicked);
//初始化相机和捕获会话
this->_camera = new QCamera(QMediaDevices::defaultVideoInput());
this->_captureSession = new QMediaCaptureSession();
//拍照功能,QImageCapture 类是一个高级图像录制类。它不是单独使用的,而是用于访问其他媒体对象的媒体录制功能
this->imageCapture.reset(new QImageCapture);
//设置捕获会话
this->_captureSession->setImageCapture(this->imageCapture.get());
connect(this->imageCapture.get(), &QImageCapture::imageCaptured, this, &QCamera_test1::processCapturedImage);
//QMediaDevices::videoInputs() 方法用于获取系统上可用的视频输入设备(如摄像头)的列表。
// 这个方法返回一个 QList<QCameraDevice>,其中每个 QCameraDevice 对象都代表一个视频输入设备
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
//for循环,遍历所有摄像头
for (const QCameraDevice& cameraDevice : cameras) {
//打印摄像头信息
qDebug() << cameraDevice.description();
//创建摄像头对象,把遍历的摄像头设备放入摄像头对象中(只有一个摄像头的时候)把遍历的cameraDevice放入摄像头对象中_camera
//设置摄像头设备,捕获会话视频输出以及摄像头。
this->_camera->setCameraDevice(cameraDevice);
//设置捕获会话视频输出
this->_captureSession->setCamera(this->_camera);
//把camera图像放入ui中;
this->_captureSession->setVideoOutput(ui.videowidget);
}
//关于sink的作用,里面包含了关于帧的一些基本信息
sink = this->_captureSession->videoSink();
connect(sink, &QVideoSink::videoFrameChanged, this, &QCamera_test1::onFrameChanged);
如果列表不为空,初始化相机和捕获会话
//if (!cameras.isEmpty()) {
// // 假设我们选择第一个摄像头(可以自己来决定)
// QCameraDevice selectedCamera = cameras.first();
// // 初始化相机对象,并设置选定的摄像头设备
// this->_camera = new QCamera(selectedCamera);
// // 初始化捕获会话对象,并设置相机和视频输出 ,把第一个相机放入媒体捕捉器中
// this->_captureSession->setCamera(this->_camera);
// //把camera图像放入ui中,在ui中显示。(选一个QWidget形状然后提升为QVideoWidget)
// this->_captureSession->setVideoOutput(ui.videowidget);
// // 开始捕获会话(如果需要的话)
// // this->_captureSession->start();
//}
//else {
// // 处理没有可用摄像头的情况
// qDebug() << "No cameras available.";
//}
}
QCamera_test1::~QCamera_test1()
{}
//打开摄像头
void QCamera_test1::btn_sopen_clicked()
{
_camera->start();
}
//保存图片
void QCamera_test1::btn_ssave_clicked() {
// 获取桌面路径
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
//获取当前时间
QDateTime currentDataTime = QDateTime::currentDateTime();
QString time = currentDataTime.toString("yyyyMMdd_hhmmss");
// 构建完整的文件路径,这里使用了一个简单的文件名,你可以根据需要更改
QString filePath = desktopPath + "/captured_image" + time + ".jpg";
// 调用 captureToFile 方法保存图片到指定路径
this->imageCapture->captureToFile(filePath);
QMessageBox::information(this, "提示", "保存成功");
}
/**
* @brief显示图像
* @param requestId
* @param img
*/
void QCamera_test1::processCapturedImage(int requestId, const QImage& img) {
Q_UNUSED(requestId);
//对获取到的图像进行缩放
QImage scaledImage = img.scaled(ui.videowidget->size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
//显示当前图像,4秒之后不再显示,默认保存到系统相册路径下
ui.viewfinder->setPixmap(QPixmap::fromImage(scaledImage));
QTimer::singleShot(4000, this, &QCamera_test1::displayImage);
displayCapturedImage();
}
//显示拍照的图像在当前第0个画布
void QCamera_test1::displayImage() {
ui.stackedWidget->setCurrentIndex(0);
}
//显示图像在当前第1个画布
void QCamera_test1::displayCapturedImage() {
ui.stackedWidget->setCurrentIndex(1);
}
//获取分辨率
void QCamera_test1::onFrameChanged(const QVideoFrame& frame) {
QSize size = frame.size();
qDebug() << "frame size: " << size << "frame rate: " << currentFrameRate;
ui.lab_resl->setText(QString("%1 x %2 @ %3 fps").arg(QString::number(size.width()), QString::number(size.height()), QString::number(currentFrameRate)));
}
//设置分辨率
void QCamera_test1::btn_setfenbianlv_clicked() {
// 设置相机的分辨率和帧率
setCameraResolutionAndFrameRate(QSize(1280, 720), 30);
}
// 设置相机分辨率和帧率的函数
void QCamera_test1::setCameraResolutionAndFrameRate(const QSize& resolution, int frameRate)
{
// 获取相机支持的格式
QList<QCameraFormat> supportedFormats = _camera->cameraDevice().videoFormats();
for (const QCameraFormat& format : supportedFormats) {
if (format.resolution() == resolution && format.maxFrameRate() >= frameRate) {
_camera->setCameraFormat(format);
currentFrameRate = format.maxFrameRate();
break;
}
}
}
3.录制视频
.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QCamera_test1.h"
#include <QCamera>
#include <QtMultimedia>
#include <QtMultimediaWidgets>
#include<QMediaCaptureSession>
#include <QMediaDevices>
#include <QImageCapture>//拍照
#include <QVideoSink>//获取分辨率
#include <QCameraDevice>//设置分辨率与帧率
#include <QMediaRecorder>//录制视频
class QCamera_test1 : public QMainWindow
{
Q_OBJECT
public:
QCamera_test1(QWidget* parent = nullptr);
~QCamera_test1();
//********************************************摄像头功能***********************************************
public:
void InitCamera();//摄像头初始化
private:
Ui::QCamera_test1Class ui;
QCamera* _camera;//摄像头
QMediaCaptureSession* _captureSession;//捕获会话
public slots:
void btn_sopen_clicked();//打开摄像头
// **********************************************拍照功能***********************************************
public:
void InitCameraCapture();//拍照初始化
void displayImage();//显示拍照的图像在当前第0个画布
void displayCapturedImage();//图像在当前第1个画布
void setCameraResolutionAndFrameRate(const QSize& resolution, int frameRate);// 设置相机分辨率和帧率的函数
private:
QScopedPointer<QImageCapture> imageCapture;//拍照
QCameraDevice* cameraDevice;//摄像头设备
QVideoSink* sink;//获取分辨率信息
int currentFrameRate; // 新增成员变量来存储当前帧率
public slots:
void btn_setfenbianlv_clicked();//设置分辨率
void onFrameChanged(const QVideoFrame& frame);//获取分辨率
void btn_ssave_clicked();//拍照并保存
void processCapturedImage(int requestId, const QImage& img);//显示图像到ui界面
// **********************************************录像功能*************************************************
public:
void InitRecorder();//录像初始化
private:
QMediaRecorder* mediaRecorder; // 录像器
QAudioInput* audioInput;//录音
public slots:
void startRecording(); // 开始录像
void stopRecording(); // 停止录像
void onRecorderStateChanged(QMediaRecorder::RecorderState state);//相机录像状态改变
void onDurationChanged(qint64 duration);//录像时间
};
.cpp
#include "QCamera_test1.h"
#include <QDateTime>
QCamera_test1::QCamera_test1(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
InitCamera();//摄像头初始化
InitCameraCapture();//相机拍照初始化
InitRecorder();//录制器初始化
}
QCamera_test1::~QCamera_test1()
{}
//********************************************摄像头功能start***********************************************
//********************************************摄像头功能start***********************************************
//********************************************摄像头功能start***********************************************
/**
* @brief 摄像头初始化
*/
void QCamera_test1::InitCamera() {
//信号与槽点击打开相机按钮
connect(ui.btn_open, &QPushButton::clicked, this, &QCamera_test1::btn_sopen_clicked);
//初始化相机和捕获会话
this->_camera = new QCamera(QMediaDevices::defaultVideoInput());
this->_captureSession = new QMediaCaptureSession();
//QMediaDevices::videoInputs() 方法用于获取系统上可用的视频输入设备(如摄像头)的列表。
// 这个方法返回一个 QList<QCameraDevice>,其中每个 QCameraDevice 对象都代表一个视频输入设备
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
//for循环,遍历所有摄像头
for (const QCameraDevice& cameraDevice : cameras) {
//打印摄像头信息
qDebug() << cameraDevice.description();
//创建摄像头对象,把遍历的摄像头设备放入摄像头对象中(只有一个摄像头的时候)把遍历的cameraDevice放入摄像头对象中_camera
//设置摄像头设备,捕获会话视频输出以及摄像头。
this->_camera->setCameraDevice(cameraDevice);
//设置捕获会话视频输出
this->_captureSession->setCamera(this->_camera);
//把camera图像放入ui中;
this->_captureSession->setVideoOutput(ui.videowidget);
}
如果列表不为空,初始化相机和捕获会话
//if (!cameras.isEmpty()) {
// // 假设我们选择第一个摄像头(可以自己来决定)
// QCameraDevice selectedCamera = cameras.first();
// // 初始化相机对象,并设置选定的摄像头设备
// this->_camera = new QCamera(selectedCamera);
// // 初始化捕获会话对象,并设置相机和视频输出 ,把第一个相机放入媒体捕捉器中
// this->_captureSession->setCamera(this->_camera);
// //把camera图像放入ui中,在ui中显示。(选一个QWidget形状然后提升为QVideoWidget)
// this->_captureSession->setVideoOutput(ui.videowidget);
// // 开始捕获会话(如果需要的话)
// // this->_captureSession->start();
//}
//else {
// // 处理没有可用摄像头的情况
// qDebug() << "No cameras available.";
//}
}
//打开摄像头
void QCamera_test1::btn_sopen_clicked()
{
_camera->start();
}
//********************************************摄像头功能end***********************************************
//********************************************摄像头功能end***********************************************
//********************************************摄像头功能end***********************************************
**********************************************拍照功能start*****************************************************************
**********************************************拍照功能start*****************************************************************
**********************************************拍照功能start*****************************************************************
/**
* @brief 拍照初始化
*/
void QCamera_test1::InitCameraCapture() {
//拍照功能,QImageCapture 类是一个高级图像录制类。它不是单独使用的,而是用于访问其他媒体对象的媒体录制功能
this->imageCapture.reset(new QImageCapture);
//设置捕获会话
this->_captureSession->setImageCapture(this->imageCapture.get());
connect(this->imageCapture.get(), &QImageCapture::imageCaptured, this, &QCamera_test1::processCapturedImage);
//信号与槽点击保存相机按钮
connect(ui.btn_save, &QPushButton::clicked, this, &QCamera_test1::btn_ssave_clicked);
connect(ui.btn_set_fenbianlv, &QPushButton::clicked, this, &QCamera_test1::btn_setfenbianlv_clicked);
//关于sink的作用,里面包含了关于帧的一些基本信息
sink = this->_captureSession->videoSink();
connect(sink, &QVideoSink::videoFrameChanged, this, &QCamera_test1::onFrameChanged);
}
//保存图片
void QCamera_test1::btn_ssave_clicked() {
// 获取桌面路径
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
//获取当前时间
QDateTime currentDataTime = QDateTime::currentDateTime();
QString time = currentDataTime.toString("yyyyMMdd_hhmmss");
// 构建完整的文件路径,这里使用了一个简单的文件名,你可以根据需要更改
QString filePath = desktopPath + "/captured_image" + time + ".jpg";
// 调用 captureToFile 方法保存图片到指定路径
this->imageCapture->captureToFile(filePath);
QMessageBox::information(this, "提示", "保存成功");
}
/**
* @brief显示图像
* @param requestId
* @param img
*/
void QCamera_test1::processCapturedImage(int requestId, const QImage& img) {
Q_UNUSED(requestId);
//对获取到的图像进行缩放
QImage scaledImage = img.scaled(ui.videowidget->size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
//显示当前图像,4秒之后不再显示,默认保存到系统相册路径下
ui.viewfinder->setPixmap(QPixmap::fromImage(scaledImage));
QTimer::singleShot(4000, this, &QCamera_test1::displayImage);
displayCapturedImage();
}
//显示拍照的图像在当前第0个画布
void QCamera_test1::displayImage() {
ui.stackedWidget->setCurrentIndex(0);
}
//显示图像在当前第1个画布
void QCamera_test1::displayCapturedImage() {
ui.stackedWidget->setCurrentIndex(1);
}
//获取分辨率
void QCamera_test1::onFrameChanged(const QVideoFrame& frame) {
QSize size = frame.size();
qDebug() << "frame size: " << size << "frame rate: " << currentFrameRate;
ui.lab_resl->setText(QString("%1 x %2 @ %3 fps").arg(QString::number(size.width()), QString::number(size.height()), QString::number(currentFrameRate)));
}
//设置分辨率
void QCamera_test1::btn_setfenbianlv_clicked() {
// 设置相机的分辨率和帧率
setCameraResolutionAndFrameRate(QSize(1280, 720), 15);
}
// 设置相机分辨率和帧率的函数
void QCamera_test1::setCameraResolutionAndFrameRate(const QSize& resolution, int frameRate)
{
// 获取相机支持的格式
QList<QCameraFormat> supportedFormats = _camera->cameraDevice().videoFormats();
for (const QCameraFormat& format : supportedFormats) {
if (format.resolution() == resolution && format.maxFrameRate() >= frameRate) {
_camera->setCameraFormat(format);
currentFrameRate = format.maxFrameRate();
break;
}
}
}
**********************************************拍照功能end*****************************************************************
**********************************************拍照功能end*****************************************************************
**********************************************拍照功能end*****************************************************************
**********************************************录像功能start*****************************************************************
**********************************************录像功能start*****************************************************************
**********************************************录像功能start*****************************************************************
/**
* @brief 初始化媒体录制器
*/
void QCamera_test1::InitRecorder() {
//初始化媒体录制器
mediaRecorder = new QMediaRecorder(this->_camera);
connect(ui.btn_start_recording, &QPushButton::clicked, this, &QCamera_test1::startRecording);
connect(ui.btn_stop_recording, &QPushButton::clicked, this, &QCamera_test1::stopRecording);
connect(mediaRecorder, &QMediaRecorder::recorderStateChanged, this, &QCamera_test1::onRecorderStateChanged);
connect(mediaRecorder, &QMediaRecorder::durationChanged, this, &QCamera_test1::onDurationChanged);
}
//开始录像
void QCamera_test1::startRecording()
{
// 初始化媒体录制器
_captureSession->setRecorder(mediaRecorder);
mediaRecorder->setVideoResolution(1280, 720); // 设置默认分辨率
mediaRecorder->setQuality(QMediaRecorder::HighQuality);
mediaRecorder->setOutputLocation(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/demo.mp4"));
mediaRecorder->setEncodingMode(QMediaRecorder::ConstantQualityEncoding);
mediaRecorder->setAudioChannelCount(mediaRecorder->audioChannelCount());
if (mediaRecorder->recorderState() != QMediaRecorder::RecordingState) {
// 获取桌面路径用于保存录像
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QDateTime currentDataTime = QDateTime::currentDateTime();
QString time = currentDataTime.toString("yyyyMMdd_hhmmss");
QString filePath = desktopPath + "/recorded_video" + time + ".mp4";
mediaRecorder->setOutputLocation(QUrl::fromLocalFile(filePath));
mediaRecorder->record();
}
else {
qDebug() << "Camera is not active or already recording.";
}
}
/**
* @brief 停止录制
*/
void QCamera_test1::stopRecording()
{
mediaRecorder->stop();
}
/**
* @brief
* @param state 相机录像状态改变
*/
void QCamera_test1::onRecorderStateChanged(QMediaRecorder::RecorderState state)
{
switch (state) {
case QMediaRecorder::RecordingState:
qDebug() << "Recording started.";
break;
case QMediaRecorder::StoppedState:
qDebug() << "Recording stopped.";
QMessageBox::information(this, "提示", "录制成功");
break;
default:
break;
}
}
/**
* @brief 录制时间
* @param duration
*/
void QCamera_test1::onDurationChanged(qint64 duration)
{
qDebug() << "Recording duration:" << QTime::fromMSecsSinceStartOfDay(duration).toString("hh:mm:ss.zzz");
ui.labelTime88->setText(QTime::fromMSecsSinceStartOfDay(duration).toString("hh:mm:ss.zzz"));
}
**********************************************录像功能end*****************************************************************
**********************************************录像功能end*****************************************************************
**********************************************录像功能end*****************************************************************