qml程序录制屏幕的方法(适用不带X window的linux环境)

在linux不带X window的系统中运行Qt程序,无法使用一般的录屏程序。
利用远程协议连接到终端也无法正确读取Qt界面。

本方法采用的思路为:利用qml的ApplicationWindow 提供的QImage image = rootWindow->grabWindow();来获取图片,再用opencv将图片压缩成视频即可。

以下为代码:

screenrecord.h

#include <opencv2/videoio.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>

class ScreenRecord : public QObject
{
    Q_OBJECT
public:
    ScreenRecord(QObject *parent = 0);

    Q_INVOKABLE bool record(QQuickWindow *rootWindow);
    Q_INVOKABLE void endRecord();

private:
    cv::VideoWriter writer;	//opencv写视频的类
    bool isRecording;
};

screenrecord.cpp

#include "screenopt.h"
#include <QDateTime>
#include <QDir>
#include <QImage>

ScreenRecord::ScreenRecord(QObject *parent): QObject(parent)
{
    isRecording = false;
}

bool ScreenRecord::record(QQuickWindow *rootWindow)
{
    QDir dir;
    //创建存储视频目录
    if (false == dir.exists("/myPath/"))
    {
        dir.mkpath("/myPath/");
    }

    if (isRecording == false)
    {
        QString filePathName = "/myPath/";
        filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");
        filePathName += QString(".avi");

        writer.open(filePathName.toStdString(), cv::VideoWriter::fourcc('M','J','P','G'), 10, cv::Size(1280, 800), true);
        isRecording = true;
    }

    QImage image = rootWindow->grabWindow();
    image = image.convertToFormat(QImage::Format_RGB888);
    //QImage转换为mat
    cv:: Mat mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
    cv::cvtColor(mat, mat, CV_RGB2BGR);	//opencv储存为BGR,故需要进行转化

    if (writer.isOpened())
    {
    	//写入一张图片
        writer.write(mat);
    }

    return true;
}

void ScreenRecord::endRecord()
{
    isRecording = false;
    writer.release();
}

将ScreenRecord 的实例注册到qml中,可以在qml中直接调用,一般在main函数中注册:

main.cpp

    int main(int argc, char *argv[])
    {
        QApplication app(argc,argv);
        QQmlApplicationEngine engine;
        ScreenRecord screenrecord;
        engine.rootContext()->setContextProperty("screenrecordObj", &screenrecord);
    	...
    	return app.exec();
    }

main .qml

    ApplicationWindow {
        id:rootWindow
        visible: true
    
       Timer{
        id:recordTimer
        interval: 100
        running: false
        repeat: true
        onTriggered: {
            if (false === screenrecordObj.record(rootWindow))
            {
                recordTimer.stop();
                screenrecordObj.endRecord();
            }
        }

        Button{
            id: startbutton
            width: 1280
            height: 800
    		onClicked:
    		{
    			//利用定时器不停的将图片写入到视频文件
				recordTimer.start()	
    		}
    	}

        Button{
            id: endbutton
            width: 1280
            height: 800
    		onClicked:
    		{
				recordTimer.end()	
				screenrecordObj.endRecord();
    		}
    	}
    	...
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值