How to use image element of QML to show sequential images?
-
Hello everyone. I 'd like to ask one question as the title. Details are as follows:
Now, I have got many images from a video capctured by a camera. Then I'd like to display them on the image element of QML sequentially using the class QQuickImageProvider. However, the UI is blocked when I finished the project. Why? My source code is as follows:#ifndef SCREENIMAGEPROVIDER_H #define SCREENIMAGEPROVIDER_H #include <QQuickImageProvider> #include <QImage> #include <QSize> #include <QColor> #include <QDebug> #include <QThread> #include <definitionheader.h> class ScreenImageProvider : public QQuickImageProvider { public: ScreenImageProvider() : QQuickImageProvider(QQuickImageProvider::Image,QQmlImageProviderBase::ForceAsynchronousImageLoading) { } QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)//这个是自动调用的。路径"image://screen",如需要使用id等参数,如"image://screen/id"等 { cout<<QString("图片供给器运行在%1线程中。").arg(quintptr(QThread::currentThreadId())); qDebug()<<"id:"<<id; qDebug()<<"进入了requestImage函数"; return this->m_image; } void setImage(const QImage& image); private: QImage m_image; }; #endif // SCREENIMAGEPROVIDER_H
#include <QGuiApplication> #include <QtQml> #include <QQmlApplicationEngine> #include <client.h> #include <definitionheader.h> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; Client* client=new Client; engine.rootContext()->setContextProperty("client",client); engine.addImageProvider("screen",client->getImageProvider()); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); cout<<QString("主线程为%1").arg(quintptr(QThread::currentThreadId())); return app.exec(); }
import QtQuick 2.4 import QtQuick.Controls 1.4 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 import QtQuick.Controls.Styles 1.4 Window { id:window; width: 800; height: 600; x:Screen.desktopAvailableWidth*0.5-width*0.5; y:Screen.desktopAvailableHeight*0.5-height*0.5; Item{ id:borderItem; anchors.fill: parent; opacity: 0; Item{ anchors.fill: parent; Image { id: imageCaptured; anchors.topMargin: 8 anchors.rightMargin: 60 anchors.leftMargin: 63 anchors.bottomMargin: 45 anchors.fill: parent; asynchronous: true; cache: false; fillMode: Image.PreserveAspectFit; Connections { target: client; onCallQmlRefeshImg: { imageCaptured.source=""; imageCaptured.source= "image://screen"; } } } } }
Thanks in advance!
-
Hi,
From your description you are likely wanting something like shown in the Image Response Provider Example.
Hope it helps
-
Hi,
From your description you are likely wanting something like shown in the Image Response Provider Example.
Hope it helps
@SGaist I have tryed that, however, the result remains the same: When paste sequential images onto QML Image element, the main GUI still freezes.
-
What do you mean by
paste
? -
@SGaist Using AsyncImageProvider. The code is as following:
#include <qqmlextensionplugin.h> #include <qqmlengine.h> #include <qquickimageprovider.h> #include <QDebug> #include <QImage> #include <QThreadPool> class AsyncImageResponse : public QQuickImageResponse, public QRunnable { public: AsyncImageResponse(const QString& id, const QSize& requestedSize,const QImage& image) : m_id(id), m_requestedSize(requestedSize), m_texture(0),m_image(image) { setAutoDelete(false); } QQuickTextureFactory* textureFactory() const { return m_texture; } void run() { m_texture = QQuickTextureFactory::textureFactoryForImage(m_image); emit finished(); } QImage m_image; QString m_id; QSize m_requestedSize; QQuickTextureFactory* m_texture; }; class AsyncImageProvider : public QQuickAsyncImageProvider { public: QQuickImageResponse* requestImageResponse(const QString& id, const QSize& requestedSize) { AsyncImageResponse* response = new AsyncImageResponse(id, requestedSize,m_image); pool.start(response); return response; } void setImage(const QImage& image) { m_image=image; } private: QThreadPool pool; QImage m_image; }; #endif // AsyncImageProvider_H
Connections { target: client; onCallQmlRefeshImg: { imageCaptured.source=""; imageCaptured.source= "image://screen"; } }
QQmlApplicationEngine engine; Client* client=new Client; engine.rootContext()->setContextProperty("client",client); engine.addImageProvider("screen",client->getImageProvider()); engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
-
@SGaist The images are captured from one camera one by one very fast. So they must be displayed using QML Image element pretty fast, which causes the main GUI to freeze. How to solve that?
-
Then why not use the Camera type ?
-
Then why not use the Camera type ?
@SGaist The format of video is unique, it is defined by ourselves. So the we have to extract pictures one by one from the video and then deliver them to the front.
-
Then you should rather implement a QtMultimedia backend for your camera, That would make more sense in the long run.