先说说opencv,直接转载:https://www.cnblogs.com/WushiShengFei/p/11202250.html
怎么得到qimage就不说了,他的核心函数为:
bool g_needstop =false; void Record() { RECT rect; //获取窗体位置大小 GetWindowRect(hd,&rect); cv::Size frameSize; frameSize.width=rect.right-rect.left; frameSize.height=rect.bottom-rect.top; cv::VideoWriter VideoWriter; if(!VideoWriter.open("d:\\1.avi",CV_FOURCC('M', 'J', 'P', 'G'),40,frameSize)) return; while(!g_needstop) { QPixmap pm; GetGDIBitmap(hd,pm,0,0,frameSize.width,frameSize.height); VideoWriter.write(ImageToMat(pm.toImage())); } VideoWriter.release(); } Mat ImageToMat(QImage img,QString imgFormat) { if(img.isNull()) return Mat(); QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); img.save(&buffer,imgFormat.toLatin1().data()); _InputArray arrSrc(ba.data(), ba.size()); Mat mat = cv::imdecode(arrSrc, CV_LOAD_IMAGE_COLOR); return mat; }
网页内容:
继续说说用avilib来生成avi文件,实际是使用mjpg格式生成,相当于每次获取到qimage,然后转成jpg,再封装成avi,核心代码:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); bf.setBuffer(&ba); bf.open(QIODevice::WriteOnly); connect(&timer,&QTimer::timeout,this,[=](){ static int i = 0; ui->label->setText(QString("%1").arg(i++)); pixmap = this->grab(); //pixmap.scaled(rect().size()); //this->render(&pixmap); //if(i%10 == 0) // pixmap.save(QString("d://%1.jpg").arg(i)); if(!pixmap.isNull()){ int ret; QByteArray ba2; QBuffer bf2(&ba2); bf2.open(QIODevice::WriteOnly); pixmap.save(&bf2,"jpg"); ret = AVI_write_frame(handle,(char*)ba2.data(),ba2.size(),1); if(ret != 0) qDebug()<<"返回错误:"<<ret; bf2.close(); } }); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { double fps = 10; QPushButton *t = qobject_cast<QPushButton*>(this->sender()); if(handle == nullptr){ handle = AVI_open_output_file((char*)"d:\\abc.avi"); AVI_set_video(handle,720,540,fps,(char*)"MJPG"); qDebug() <<"start avi"; t->setText("Stop"); timer.start(1000/fps); }else{ qDebug() <<"end avi"; t->setText("Start"); timer.stop(); AVI_close(handle); handle = nullptr; } }
这里有个问题,如果qbytearray定义为全局,那么保存的avi超级大,而且画面不会动,只有启动的画面。而设置为局部变量,则可以完整看到屏幕变化,暂时还不理解。