前言:
前面几篇教程,都是介绍了使用Qt5.15.2(qml)取出视频帧,本篇解决从Qt6.2.1中取出视频帧
本教程是在Qt6.2.1(qml)摄像头显示 示例代码的基础上修改
注意,本教程示例,在windows下,只能在VS编译中运行
一、增加图像提供者类
定义类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,头文件如下
#include <QObject>
#include <QVideoFrame>
class Tool : public QObject
{
Q_OBJECT
public:
explicit Tool(QObject *parent = nullptr);
//设置并处理已获取视频帧
Q_INVOKABLE void setVideoFrame(const QVideoFrame frame);
signals:
};
源文件关键代码
/*!
* \brief Tool::setVideoFrame 设置并处理已获取视频帧
* \param frame 已获取视频帧
*/
void Tool::setVideoFrame(const QVideoFrame frame)
{
qDebug()<<"Tool::setVideoFrame"<<frame;
const QImage image = frame.toImage();
//将视频帧放入图像提供者
ImageProvider::setImage(image);
}
三、主函数main()修改
1.初始化,并增加图像提供者
添加代码如下
engine.addImageProvider(QLatin1String("imageProvider"), new ImageProvider);
2.注册帧的处理类
添加代码如下
qmlRegisterType<Tool_VideoFrames>("com.xdqd.classes", 1, 0, "Tool");
四、修改UI显示
如下所示,是笔者修改的UI
qml中增加如下信号处理器
Connections {
target: videoOutput.videoSink
function onVideoFrameChanged(frame) {
//设置并处理已获取视频帧
tool.setVideoFrame(frame)
image.source = "image://imageProvider/0"
image.source = "image://imageProvider/1"
}
}
注:Image的源也可用使用随机数,但必须要更换下,否则不会触发图像的变化
运行效果如下
本教程示例源码
后记
感觉使用Qt6,比Qt5的代码简洁多了,但Qt6多媒体,在Windows下,只支持VS编译器,不支持win7,官方只提供64位预编译库
笔者受时间限制,发现android上无法正常运行,会异常退出。
调试发现QVideoFrame::toImage();一执行就会异常退出,提示如下:
Cannot make QOpenGLContext current in a different thread
我们还是等待官方修复吧
PS.Qt6的多媒体模块仍然存在不少坑,请小伙伴们注意测试下