QT+OPENCV或AVILIB实现录屏功能

先说说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;
}


网页内容:

abc.pdf


继续说说用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超级大,而且画面不会动,只有启动的画面。而设置为局部变量,则可以完整看到屏幕变化,暂时还不理解。

本文为3YL原创,转载无需联系,但请注明来自labisart.com。

原创文章不易,如果觉得有帮助,可打赏或点击右侧广告支持:

查看打赏记录

发表评论请遵守党国法律!后台审核后方可显示!
  • 最新评论
  • 总共0条评论
  • Blog v1.1© 2024 labisart.com 版权所有 | 联系:labartwork@163.com