[Development] How fast grab a QML item's content to image when it updates?
Konstantin Tokarev
annulen at yandex.ru
Tue Dec 12 16:52:46 CET 2017
12.12.2017, 16:53, "Denis Shienkov" <denis.shienkov at gmail.com>:
> > Did you try QQuickItem::grabToImage?
>
> Of course, it is veeery slowly.
I guess your best bet then is hardware grabbing video output
>
> 12.12.2017 16:40, Konstantin Tokarev пишет:
>> 12.12.2017, 16:13, "Denis Shienkov" <denis.shienkov at gmail.com>:
>>> Hi all...
>>>
>>> Is it possible to grab a QQuickItem content (e.g. with all sub-items)
>>> when an item changes?
>> Did you try QQuickItem::grabToImage?
>>
>>> E.g. with widgets I use the following code:
>>>
>>> bool MyWidget::event(QEvent *event)
>>> {
>>> if (event->type() == QEvent::UpdateRequest)
>>> myGrab();
>>> return QWidget::event(event);
>>> }
>>>
>>> void MyWidget::myGrab()
>>> {
>>> ...
>>> QBackingStore *store = backingStore();
>>> Q_ASSERT(store);
>>>
>>> QPaintDevice *pdev = store->paintDevice();
>>> const auto image = dynamic_cast<QImage *>(pdev);
>>> ...
>>> }
>>>
>>> it is very fast (as I know)...
>>>
>>> But with the QML I got a troubles: I can 'grab' the sourceItem, using
>>> the FBO and private functions, but the fbo::toImage() is too slow (~24
>>> msecs),
>>> and I don't know how to intercept the signal when a watched item updates:
>>>
>>> Grabber::Grabber(QQuickItem *parent)
>>> : QQuickItem(parent)
>>> {
>>> setFlag(QQuickItem::ItemHasContents);
>>> }
>>>
>>> // Where sourceItem - is a watched item.
>>> void Grabber::setSourceItem(QQuickItem *sourceItem)
>>> {
>>> if (sourceItem == m_sourceItem)
>>> return;
>>> m_sourceItem = sourceItem;
>>> emit sourceItemChanged(m_sourceItem);
>>> update();
>>> }
>>>
>>> QSGNode *Grabber::updatePaintNode(QSGNode *oldNode,
>>> UpdatePaintNodeData *updatePaintNodeData)
>>> {
>>> Q_UNUSED(updatePaintNodeData);
>>>
>>> if (!m_sourceItem)
>>> return oldNode;
>>>
>>> QSGRootNode root;
>>> root.appendChildNode(QQuickItemPrivate::get(m_sourceItem)->itemNode());
>>>
>>> const QScopedPointer<QSGRenderer> renderer(
>>> QQuickItemPrivate::get(this)->
>>> sceneGraphRenderContext()->createRenderer());
>>>
>>> renderer->setRootNode(&root);
>>>
>>> const QSize size(m_sourceItem->width(), m_sourceItem->height());
>>> renderer->setDeviceRect(size);
>>> renderer->setViewportRect(size);
>>> renderer->setProjectionMatrixToRect(QRectF(QPointF(), size));
>>> renderer->setClearColor(Qt::transparent);
>>>
>>> QOpenGLFramebufferObject fbo(size);
>>> renderer->renderScene(BindableFbo(&fbo));
>>> fbo.release();
>>>
>>> QElapsedTimer et;
>>> et.start();
>>> const QImage image = fbo.toImage(); // TOO LONG ~24 msec!
>>> qDebug() << "Elapsed:" << et.elapsed();
>>>
>>> return oldNode;
>>> }
>>>
>>> it is very fast (as I know).
>>>
>>> But with the QML I got a troubles: I can 'grub' an item, using the FBO,
>>>
>>> but the toImage() method is too slow (~24 msecs), and I don't know how
>>>
>>> to intercept a signal when the watched item updates:
>>>
>>> Grabber::Grabber(QQuickItem *parent)
>>> : QQuickItem(parent)
>>> {
>>> setFlag(QQuickItem::ItemHasContents);
>>> }
>>>
>>> QSGNode *Grabber::updatePaintNode(QSGNode *oldNode,
>>> UpdatePaintNodeData *updatePaintNodeData)
>>> {
>>> Q_UNUSED(updatePaintNodeData);
>>>
>>> if (!m_sourceItem)
>>> return oldNode;
>>>
>>> QSGRootNode root;
>>> root.appendChildNode(QQuickItemPrivate::get(m_sourceItem)->itemNode());
>>>
>>> const QScopedPointer<QSGRenderer> renderer(
>>> QQuickItemPrivate::get(this)->
>>> sceneGraphRenderContext()->createRenderer());
>>>
>>> renderer->setRootNode(&root);
>>>
>>> const QSize size(m_sourceItem->width(), m_sourceItem->height());
>>> renderer->setDeviceRect(size);
>>> renderer->setViewportRect(size);
>>> renderer->setProjectionMatrixToRect(QRectF(QPointF(), size));
>>> renderer->setClearColor(Qt::transparent);
>>>
>>> QOpenGLFramebufferObject fbo(size);
>>> renderer->renderScene(BindableFbo(&fbo));
>>> fbo.release();
>>>
>>> QElapsedTimer et;
>>> et.start();
>>> const QImage image = fbo.toImage(); // TOO LONG!
>>> qDebug() << "Elapsed:" << et.elapsed();
>>>
>>> return oldNode;
>>> }
>>>
>>> _______________________________________________
>>> Development mailing list
>>> Development at qt-project.org
>>> http://lists.qt-project.org/mailman/listinfo/development
--
Regards,
Konstantin
More information about the Development
mailing list