QR扫码综合示例教程(十二)Qt5.15.2(qml)取出视频帧 原始帧

 前言:

终于要来点干货了,本次教程会取出视频帧,笔者使用的是Qt5.15.2

在Qt5.15.2(qml)摄像头显示示例的基础上修改

一、增加图像提供者类

定义类ImageProvider,头文件如下

class ImageProvider : public QQuickImageProvider
{
public:
    explicit ImageProvider();

    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;

    //设置图像
    static void setImage(const QImage &image);
signals:

private:
    //存储最后一帧
    static QImage ms_image;
};

源文件关键代码如下

//qml调用,以获取显示图像
QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
    qDebug()<<"ImageProvider::requestPixmap"<<id;
    int width = ms_image.width();
    int height = ms_image.height();

    if (size)
        *size = QSize(width, height);

    return QPixmap::fromImage(ms_image.scaled(requestedSize.width() > 0 ? requestedSize.width() : width,
                                              requestedSize.height() > 0 ? requestedSize.height() : height));
}

//设置最后一帧图像
void ImageProvider::setImage(const QImage &image)
{
    qDebug()<<"ImageProvider::setImage"<<image;
    ms_image = image;
}

  二、增加取帧的处理类

新建一个类Tool_VideoFrames,在类内部,实例化QVideoProbe,并设置源

关键代码如下

connect( &m_probe, &QVideoProbe::videoFrameProbed,
             this, &Tool_VideoFrames::onProcssFrame );


void Tool_VideoFrames::setQmlCamera(QObject *qmlCamera)
{
    this->m_qmlCamera = qmlCamera;
    if( m_qmlCamera )
    {
        //将QML对象转换为C++对象
        m_camera = qvariant_cast< QCamera* >( m_qmlCamera->property( "mediaObject" ) );

        //将类QVideoFrameProbe的实例化对象_probe的数据来源设为_camera
        m_probe.setSource( m_camera );

    }
    qDebug() << "set Camera success!";

}

//处理获取到的视频帧
void Tool_VideoFrames::onProcssFrame(const QVideoFrame &frame)
{
    const QImage image = frame.image();
    //将视频帧放入图像提供者
    ImageProvider::setImage(image);
    emit newVideoFrame(image);
}

三、主函数main()修改

1.初始化,并增加图像提供者

添加代码如下

engine.addImageProvider(QLatin1String("imageProvider"), new ImageProvider);

2.注册帧的处理类

添加代码如下

qmlRegisterType<Tool_VideoFrames>("com.xdqd.classes", 1, 0, "Tool_VideoFrames");

 四、修改UI显示

如下所示,是笔者修改的UI

QR扫码综合示例教程(十二)Qt5.15.2(qml)取出视频帧 原始帧

注:一定记得Image的cache属性要设置为false,否则图像不会发生变化

修改qml文件,关键代码如下

Tool_VideoFrames {
        id: tool_VideoFrames
        //此处会调用C++类 CameraFromQML中, 属性的setQmlCamera( QObject *qmlCamera ) 方法
        qmlCamera: camera

    }

    Connections {
        target: tool_VideoFrames
        function onNewVideoFrame(videoFrame){
            //必须要更换下,否则图像不会发生变化
            image.source = "image://imageProvider/0"
            image.source = "image://imageProvider/1"
        }
    }

注:Image的源也可用使用随机数,但必须要更换下,否则不会触发图像的变化

程序运行如下

 QR扫码综合示例教程(十二)Qt5.15.2(qml)取出视频帧 原始帧

 大功告成

本教程示例源码

后记:

取视频帧成功,只使用Qt/qml的库,看起来不错。有细心的小伙伴已经注意了,怎么预览画面与取出的帧不太一样?没错,可能是一样的,但若换个摄像头,取出的帧就可能发生倒置或镜像。若使用的摄像头是确定的,这没问题,但无法做成通用程序。

下一往篇,继续讲解处理方法

上一篇:QR扫码综合示例教程(十一)Qt6.2.1(qml)摄像头显示


下一篇:JOISC 2020 Day 3