QT + OPENCV实现录屏功能

基本的原理就是通过截屏,然后opencv合成avi视频

screenthread.h

线程
#pragma once
#include <QThread>
#include "recordscreen/recordscreen.h"

class ScreenThread :public QThread {
public:
	void ScreenThread::run()
	{
		RecordScreen* record = new RecordScreen;
		record->screenStart();
		exec();
	}

	 ScreenThread::~ScreenThread()
	{
		if (record)
		{
			delete record;
			record = NULL;
		}
	}
private:
	RecordScreen* record =NULL;
};

mainwindow主函数调用,可以通过按钮等

/**
*录屏
*/
void  MainWindow::recordScreen()
{
	if (!record)
	{
		record = new ScreenThread;
	}	
	record->start();
	statusBar()->showMessage(QStringLiteral("开始录屏"));
}
/**
* 结束录屏实际做转换视频操作
*/
void  MainWindow::endRecordScreen()
{
	if (record)
	{
		record->quit();
		//delete record;
		record = NULL;
	}
	
	QDesktopWidget *desktop = QApplication::desktop();
	int width = desktop->width();
	int height = desktop->height();
	
	QString path = QDir::currentPath();//当前工作路径
	QString videopath = path + "/images/screenVideo/";
	QDir dir(videopath);
	String cou = std::to_string(dir.count() - 1);

	String videoNamePath = "images/screenVideo/Videotest" + cou + ".avi";
	VideoWriter video(videoNamePath, CV_FOURCC('X', 'V', 'I', 'D'), 5.0/*27.0*/, Size(width, height));

	String img_path = "D:\\photoscreen\\";
	vector<String> img;
	

	if (!dir.exists()) {
		bool ok = dir.mkdir(videopath);//只创建一级子目录,即必须保证上级目录存在
								  //return ;
	}
	dir.setFilter(QDir::Files);

	QString photopath =path+ "/images/photoscreen/";
	QDir *pdir = new QDir(photopath);
	QStringList filter2;
	filter2 << "*.png";
	pdir->setNameFilters(filter2); //过滤文件类型
	QList<QFileInfo> *fileInfo = new QList<QFileInfo>(pdir->entryInfoList(filter2));
	int count = fileInfo->count();  //文件个数
									//glob(img_path, img, false);

									//size_t count = img.size();
									//size_t count = 80;
	for (size_t i = 0; i < count; i++)
	{
		stringstream str;
		str << i << ".png";
		string tem = photopath.toStdString() + str.str();
		Mat image = imread(photopath.toStdString() + str.str());
		if (!image.empty())
		{
			cv::resize(image, image, Size(width, height));
			video << image;
			cout << "正在处理第" << i << "帧" << endl;
		}
	}
	statusBar()->showMessage(QStringLiteral("录屏结束"));
}

/**
*回放
*/
void  MainWindow::playback()
{
	QDesktopWidget *desktop = QApplication::desktop();

	QString path = QDir::currentPath();//当前工作路径
	QString videopath = path + "/images/screenVideo/";
	QDir dir(videopath);
	QString cou = QString::number(dir.count() - 2);

	QString videoNamePath = videopath + "Videotest" + cou + ".avi";
	QMediaPlayer* mediaPlayer = new QMediaPlayer;
	QRect desktopRect = QApplication::desktop()->availableGeometry();

	mediaPlayer->setMedia(QUrl(videoNamePath));
	QVideoWidget* videoWidget = new QVideoWidget;
	mediaPlayer->setVideoOutput(videoWidget);


	videoWidget->resize(desktop->width() - 10, desktop->height() - 80);
	videoWidget->move((desktop->width() - videoWidget->width() - 10) / 2, (desktop->height() - videoWidget->height() - 70) / 2);
	videoWidget->show();
	mediaPlayer->play();
}

recordscreen.cpp

#include "recordscreen/recordscreen.h"
#include <QObject>
#include <QDesktopWidget>
#include <QtWidgets/QApplication>


RecordScreen::RecordScreen()
{
	count = 0;
}

/**
* 开始录屏
*/
void RecordScreen::screenStart()
{
	QString path = QDir::currentPath();//当前工作路径
	path += "/images/photoscreen/";

	QDir dir(path);
	if (!dir.exists()) {
		bool ok = dir.mkdir(path);//只创建一级子目录,即必须保证上级目录存在
		//return ;
	}
	QStringList filter; //过滤器
	filter.append("*");
	QDirIterator it(path, filter, QDir::Files, QDirIterator::Subdirectories);
	while (it.hasNext()) { //若容器中还有成员,继续执行删除操作
		dir.remove(it.next());
	}
	
	time = new QTimer();
	//time->setInterval(1);
	connect(time,SIGNAL(timeout()),this,SLOT(shotScreen()));
	//connect(time, &QTimer::timeout, this, [=] {

	//	shotScreen();

	//});
	time->start(10);
}

void RecordScreen::screenEnd()
{
	time->stop();
}

**recordscreen.cpp**
/**
* 录屏保存为图片
*/
void RecordScreen::shotScreen()
{
	int width = QApplication::desktop()->width();
	int height = QApplication::desktop()->height();
	QPixmap pix = QPixmap::grabWindow(QApplication::desktop()->winId(),0,0,width,height);
	QString path = QDir::currentPath();//当前工作路径
	path += "/images/photoscreen/";
	count++;
	QString fileName = QString::number(count);
	QString format = ".png";
	fileName = path + fileName + format;
	bool ok = pix.save(fileName);
	if (ok)
	{
		qDebug() << "save photo success";
	}
	else
	{
		qCritical() << "save photo unsuccess";
	}
}


RecordScreen::~RecordScreen()
{
}

recordscreen.h

#ifndef RECORD_SCREEN_H
#define RECORD_SCREEN_H

#include <QtGui>
#include <QTime>
#include <QWidget>

class RecordScreen:public QObject {
	Q_OBJECT
public:
	RecordScreen();
	~RecordScreen();
	void screenStart();
	void screenEnd();

public slots:
	void shotScreen();



private:
	int count;
	QTimer* time;


};



#endif // !RECORD_SCREEN_H


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值