/******** CScreenShot.h **************/
#ifndef __CSCREENSHOT_H
#define __CSCREENSHOT_H
#include <QRunnable>
#include <QPixmap>
#include <QMutex>
#include <QWaitCondition>
#include <QThread>
#define CollectGarbage(className) class className##Collect{ public: ~className##Collect(){ if ( NULL != instance ){delete instance;instance = NULL;}}}; static className##Collect GarCollect;
class CScreenShot : public QThread
{
Q_OBJECT
public:
~CScreenShot();
static CScreenShot* getSingletonInstance(); ///< 单例
void setControl(bool bStop);
void getPixMap(const QPixmap& pix);
protected:
void run();
private:
Q_DISABLE_COPY(CScreenShot);
CollectGarbage(CScreenShot);
CScreenShot();
static CScreenShot* instance;
bool m_bStop;
char* frameBuffer;
QPixmap m_pix;
QMutex mutex;
QWaitCondition wait;
};
#endif// cscreenshot.h
/******** CScreenShot.cpp **************/
#ifdef __cplusplus
extern "C"
{
#include <avilib.h> // avilib库的头文件
}
#endif
#include "CScreenShot.h"
#include <QBuffer>
#include <QDateTime>
#include <QThread>
#include <QDir>
#include <QString>
#include <QByteArray>
CScreenShot* CScreenShot::instance = NULL;
CScreenShot* CScreenShot::getSingletonInstance()
{
if(instance == NULL)
{
instance = new CScreenShot();
}
return instance;
}
CScreenShot::CScreenShot() :m_bStop(false)
{
}
CScreenShot::~CScreenShot(){}
void CScreenShot::getPixMap(const QPixmap& pix){
m_pix = pix.scaled(400,300);
wait.wakeOne();// 获取一次图片就唤醒一次线程,制作视频
}
void CScreenShot::run(){
QString tmpFile= QDir::currentPath() + "/" + QDateTime::currentDateTime().toString("hhmmss")+".avi";
QByteArray byte = tmpFile.toUtf8();
char* filename = byte.data();//以当前时间定义文件名和路径
avi_t* out_fd = AVI_open_output_file(filename); //把文件描述符绑定到此文件上
if(out_fd == NULL){ return;}
AVI_set_video(out_fd,160,120,70,"MJPG");//设置视频文件的格式
int keyfame = 1;
while(!m_bStop)
{
QMutexLocker lock(&mutex);
wait.wait(&mutex); // 等待新的图片过来
QByteArray frame;
QBuffer buffer(&frame);
buffer.open(QIODevice::WriteOnly);
m_pix.save(&buffer, "jpg");
//m_pix.save(QDateTime::currentDateTime().toString("hhmmss") + ".jpg","jpg");
if(frame.data() != NULL && frame.length() !=0)
{
if(AVI_write_frame(out_fd,frame.data(),frame.length(),keyfame) < 0) {}
else{ keyfame = 0;}
}
}
AVI_close(out_fd);
}
/** 在其他页面构建函数体内定时将当前centraLWidget页面截取传给线程处理成AVI视频即可 **/
mytimer = new QTimer(this);
mytimer->setInterval(150);
mytimer->start();
CScreenShot::getSingletonInstance()->start();
connect(mytimer, &QTimer::timeout,this,[&](){
if (!mytimer->isActive()){mytimer->start();}
QPixmap pix = QPixmap::grabWindow(CentralWidget->winId());// Qt 4.x就用这个方法,这里为了少写个函数用lambda表达式替代。
CScreenShot::getSingletonInstance()->getPixMap(pix);});
}
Qt之AVI录屏
于 2022-01-22 21:23:01 首次发布