作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
前言
想要在 QML 中实时显示图像,目前博主已知的方法有3个,分别是继承 QQuickItem、继承 QQuickPaintedItem、以及使用 QQuickImageProvider。这篇文章来介绍一下如何使用 QQuickImageProvider 调用相机实时显示图像,方便后期自己回顾
1. 使用 OpenCV 实现相机控制,图像采集
自定义 Camera 类,通过 OpenCV 的 VideoCapture 来打开相机获取图像
void Camera::updateFrame()
{
if ( m_camera.isOpened() ) {
cv::Mat3b mat;
m_camera >> mat;
QImage image((const unsigned char *)(mat.data), mat.cols, mat.rows, mat.cols * 3, QImage::Format_RGB888);
QImage ret = image.rgbSwapped();
emit updateImage(ret.convertToFormat(QImage::Format_RGB888));
}
}
2. 自定义 ImageProvider 类继承于 QQuickImageProvider
这里需要重新实现接口 requestPixmap
class ImageProvider : public QQuickImageProvider
{
public:
ImageProvider();
void updateImage(QImage &image); // 更新图像
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
private:
QImage m_image;
};
3. 自定义 CameraControl 类
此类主要实现相机的控制并且当相机刷新图像时,能够更新 ImageProvider 中的图像。还需要提供打开相机的接口给QML调用
class CameraControl : public QObject
{
Q_OBJECT
public:
explicit CameraControl(QObject *parent = nullptr);
~CameraControl();
Q_INVOKABLE void openCamera(int interval);
inline ImageProvider *getImageProvider() { return m_imageProvider; }
signals:
void callQmlRefeshImg();
private:
ImageProvider *m_imageProvider;
Camera *m_camera;
};
CameraControl::CameraControl(QObject *parent) : QObject(parent)
{
m_imageProvider = new ImageProvider();
m_camera = new Camera();
connect(m_camera, &Camera::updateImage, [&](QImage image){
m_imageProvider->updateImage(image); // 更新图像
emit callQmlRefeshImg(); // 发送信号,让QML也更新图像
});
}
CameraControl::~CameraControl()
{
delete m_camera;
}
void CameraControl::openCamera(int interval)
{
m_camera->openCamera(interval);
m_camera->startWork();
}
4. 在主函数中使用 addImageProvider 函数添加图片入口
CameraControl cameraCtl;
engine.rootContext()->setContextProperty("cameraCtl", &cameraCtl);
engine.addImageProvider(QLatin1String("QYCamera"), cameraCtl.getImageProvider());
5. 在 QML 中使用全局的 cameraCtl 刷新图像
收到信号后修改 Image 的 source 属性即可实现图像不断刷新
Image {
id: image
anchors.fill: parent
Component.onCompleted: cameraCtl.openCamera(100) // 打开相机,每 100 ms 取一张图片
Connections {
target: cameraCtl
// 收到信号刷新图片
onCallQmlRefeshImg: image.source = "image://QYCamera/" + Math.random()
}
}