qml显示视频帧(QQuickImageProvider)
一、实现方式
解码视频可以选择:opencv、ffmpeg等。
显示视频可以选择:Qt Multimedia、QQuickImageProvider、ShaderEffect、自定义QQuickItem等。
本文使用opencv解码视频,QQuickImageProvider显示视频。
二、QQuickImageProvider 中,requestImage 和 requestTexture区别
在 QQuickImageProvider 中,requestImage 和 requestTexture 的区别主要体现在 调用时机、返回数据类型 和 性能优化 上。以下是详细对比:
核心区别
| 特性 | requestImage | requestTexture |
|---|---|---|
| 返回类型 | QImage(CPU 内存中的图像) | QQuickTextureFactory*(GPU 纹理工厂) |
| 调用时机 | QML 需要 CPU 可操作的图像时(如截图、软件处理) | QML 需要直接渲染到 GPU 时(如视频、动画) |
| 性能 | 较高开销(需 CPU → GPU 上传) | 高性能(直接生成 GPU 纹理,零拷贝) |
| 典型用例 | 静态图片、需像素级操作的图像 | 视频帧、动态内容、高频更新 |
如何选择实现哪个方法?
| 需求 | 实现方法 | 理由 |
|---|---|---|
| 静态图片 | requestImage | 简单易用,兼容性好 |
| 视频/实时渲染 | requestTexture | 避免 CPU-GPU 拷贝,性能更高 |
| 需要像素操作 | requestImage | 可直接访问像素数据 |
| 跨平台 GPU 渲染 | requestTexture | 统一适配不同图形后端 |
Qt 的默认行为

三、示例代码
目录结构:

视频解码类(VideoDecoder)
VideoDecoder.h
#ifndef VIDEODECODER_H
#define VIDEODECODER_H#include <QObject>
#include <QMutex>
#include <opencv2/videoio.hpp>
#include <atomic>class VideoDecoder : public QObject {Q_OBJECT
public:explicit VideoDecoder(QObject *parent = nullptr);~VideoDecoder();public slots:void open(const QString &filePath);void stop();void setPosition(int ms);signals:void frameReceived(const QImage &frame);void durationChanged(int ms);void positionChanged(int ms);private:void decodeLoop();cv::VideoCapture m_cap;std::atomic<bool> m_running{false};std::thread m_decodeThread