QGraphicsView and QML: big image is not shown



  • Hi,

    I have a problem that my Images are not shown when they exceed pow (2,24). E.g. 4000x4100 image works,
    while 4000x4200 does not.

    I use QML with some custom QML Types, using QGraphicsScene and QGraphicsView.
    Not using QML (and our custom rendering), and just adding the pixmap to the QGraphicsView works ok.

    Any hints on how to fix this are welcome.

    The QML contains the following qml type :

        QuickGraphicsSceneItem
        {
            id: graphics_scene_item
            objectName: "graphicsSceneItem"
            anchors.fill: parent
            focus: true
        }
    
    

    The Image is added as follows:

    void addImageToScene(QGraphicsScene* scene, QGraphicsView* view, QString fileName)
    {
        QImage q_image{ fileName };
    
        QPixmap pixmap;
        pixmap.convertFromImage(q_image);
    
        QGraphicsPixmapItem * pixmapItem = new QGraphicsPixmapItem(pixmap);
        pixmapItem->setZValue(0);
        scene->addItem(pixmapItem);
    
        view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
    
    }
    
    

    The QuickGraphicsSceneItem header file:

    class StrippedDownQuickGraphicsSceneItem : public QQuickFramebufferObject
    {
        Q_OBJECT
    
    public:
        StrippedDownQuickGraphicsSceneItem(QQuickItem * parent = nullptr);
        virtual ~StrippedDownQuickGraphicsSceneItem();
    
        QGraphicsScene* getGraphicsScene() const;
        QGraphicsView* getGraphicsView() const;
    
        static void registerQMLType();
    
        virtual QSGNode * updatePaintNode(QSGNode * node, UpdatePaintNodeData * nodeData);
        virtual QQuickFramebufferObject::Renderer * createRenderer() const;
    
    signals:
        void sceneChanged();
        void lateUpdate();
    
        private slots:
        void handleWindowChanged(QQuickWindow * window);
        void sync();
        void updateRegion(const QList<QRectF> & region);
        void doLateUpdate();
    
    private:
    
        std::unique_ptr<QGraphicsScene> m_graphics_scene;
        std::unique_ptr<QGraphicsView> m_graphics_view;
    };
    

    While the cpp file for the Scen Item is:

    class GraphicsViewRenderer : public QQuickFramebufferObject::Renderer
    {
    public:
        GraphicsViewRenderer(QGraphicsView* graphicsView)
            : m_graphics_view(graphicsView)
        {
        }
    
        QOpenGLFramebufferObject *createFramebufferObject(const QSize & size) override
        {
            QOpenGLFramebufferObjectFormat format;
            format.setSamples(16);
            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
            return new QOpenGLFramebufferObject(size, format);
        }
    
        void render() override
        {
            QOpenGLPaintDevice paint_device(m_graphics_view->viewport()->size() );
            QPainter painter(&paint_device);
            painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    
            clearFrameBuffer(painter);
    
            m_graphics_view->render(&painter);
        }
    
    private:
    
        void clearFrameBuffer(QPainter & painter)
        {
            const QSize viewport_size = painter.viewport().size();
    
            painter.beginNativePainting();
    
            glViewport(0, 0, viewport_size.width(), viewport_size.height());
            glClearColor(0.0, 0.0, 0.0, 0.0);
    #if !defined(QT_OPENGL_ES_2)
            glClearDepth(1.0f);
    #else
            glClearDepthf(1.0f);
    #endif
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
            painter.endNativePainting();
        }
    
        QGraphicsView* m_graphics_view;
    };
    
    
    //-------------------------------------------------------------------------
    void StrippedDownQuickGraphicsSceneItem::registerQMLType()
    {
        qmlRegisterType <StrippedDownQuickGraphicsSceneItem>("com.medicim.qmlcomponents", 1, 0, "QuickGraphicsSceneItem");
    }
    
    //-------------------------------------------------------------------------
    StrippedDownQuickGraphicsSceneItem::StrippedDownQuickGraphicsSceneItem(QQuickItem * parent)
        : QQuickFramebufferObject(parent)
        , m_graphics_scene(new QGraphicsScene(this))
        , m_graphics_view(new QGraphicsView(m_graphics_scene.get()))
    {
        connect(this, SIGNAL(windowChanged(QQuickWindow *)), this, SLOT(handleWindowChanged(QQuickWindow *)));
    
        setFlags(QQuickItem::ItemHasContents);
        setAntialiasing(true);
        setAcceptedMouseButtons(Qt::AllButtons);
        setAcceptHoverEvents(true);
        setMirrorVertically(true);
    
        updateInputMethod(Qt::ImQueryAll);
    
        m_graphics_scene->setBackgroundBrush(QBrush(Qt::black));
        m_graphics_view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    }
    
    //-------------------------------------------------------------------------
    StrippedDownQuickGraphicsSceneItem::~StrippedDownQuickGraphicsSceneItem() = default;
    
    //-------------------------------------------------------------------------
    QGraphicsScene * StrippedDownQuickGraphicsSceneItem::getGraphicsScene() const
    {
        return m_graphics_scene.get();
    }
    
    //-------------------------------------------------------------------------
    QGraphicsView * StrippedDownQuickGraphicsSceneItem::getGraphicsView() const
    {
        return m_graphics_view.get();
    }
    
    //-------------------------------------------------------------------------
    void StrippedDownQuickGraphicsSceneItem::handleWindowChanged(QQuickWindow * window)
    {
        if (window)
        {
            connect(this, &StrippedDownQuickGraphicsSceneItem::lateUpdate, this, &StrippedDownQuickGraphicsSceneItem::doLateUpdate, Qt::QueuedConnection);
    
            connect(window, SIGNAL(heightChanged(int)), this, SLOT(sync()));
            connect(window, SIGNAL(widthChanged(int)), this, SLOT(sync()));
    
            connect(m_graphics_scene.get(), &QGraphicsScene::changed, this, &StrippedDownQuickGraphicsSceneItem::updateRegion, Qt::QueuedConnection);
            connect(m_graphics_scene.get(), SIGNAL(selectionChanged()), this, SLOT(update()));
            connect(m_graphics_view.get(), SIGNAL(sceneChanged()), this, SLOT(update()));
    
            window->resetOpenGLState();
            window->setColor(QColor(0, 0, 0, 0));
            window->setClearBeforeRendering(true);
        }
    }
    
    //-------------------------------------------------------------------------
    void StrippedDownQuickGraphicsSceneItem::sync()
    {
        m_graphics_view->resize(window()->width(), window()->height());
        m_graphics_view->viewport()->resize(window()->width(), window()->height());
    
        emit lateUpdate();
    }
    
    //-------------------------------------------------------------------------
    void StrippedDownQuickGraphicsSceneItem::doLateUpdate()
    {
        m_graphics_view->fitInView(m_graphics_scene->sceneRect(), Qt::KeepAspectRatio);
    }
    
    //-------------------------------------------------------------------------
    void StrippedDownQuickGraphicsSceneItem::updateRegion(const QList<QRectF> & region)
    {
        Q_UNUSED(region)
    
            /** Update the whole thing instead of just the required regions. Updating only the required regions
            causes all kinds of glitches. */
            update();
    }
    
    //-------------------------------------------------------------------------
    QSGNode * StrippedDownQuickGraphicsSceneItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData * nodeData)
    {
        if (node == 0)
        {
            node = QQuickFramebufferObject::updatePaintNode(node, nodeData);
            QSGSimpleTextureNode * texture_node = static_cast<QSGSimpleTextureNode *>(node);
            texture_node->setRect(boundingRect());
            texture_node->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
    
            return node;
        }
    
        return QQuickFramebufferObject::updatePaintNode(node, nodeData);
    }
    
    //-------------------------------------------------------------------------
    QQuickFramebufferObject::Renderer *StrippedDownQuickGraphicsSceneItem::createRenderer() const
    {
        return new GraphicsViewRenderer(m_graphics_view.get());
    }
    
    

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    What version of Qt are you using ?
    On what OS ?
    Which architecture ?
    What type of image is that ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.