Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to solve the problem that qgrapics-related classes cannot display content Completely when the picture is huge(30000x40000)



  • my question is: For the purpose of displaying giant-sized pictures (30000x40000), I used qgraphicscene-related classes and methods. But after successfully loading the data and displaying it , I found that the display was only partial, with a black area at the bottom of the scene, indicating that the program did not successfully display the contents of the picture. In the code, I used qgraphicsitemgroup to save the image, because QGraphicsPixmapItem might not be able to save such huge amounts of data, so I divided the image into pieces. I guess there are some restrictions on the classes involved or are the methods used wrong? So I wanted to ask if there were any relevant ways to break this limit or if there were other ways to paint such a huge picture.

        void PicView::addImage(const QImage& image, int row, int col)
        {
        map = new QGraphicsPixmapItem(QPixmap::fromImage(image));
            map->setPos(row, col);
            imgGroup->addToGroup(map);
            m_bottom = image.height() + col;
            m_right = image.width() + row;
            scene->setSceneRect(imgGroup->sceneBoundingRect());
        }
    
        PicTileWidget::PicTileWidget()
        {
        scene = new QGraphicsScene();
        view = new PicView(scene);
        view->setBackgroundBrush(QBrush(Qt::red, Qt::SolidPattern));
        QHBoxLayout* layout = new QHBoxLayout();
        setLayout(layout);
        layout->addWidget(view);
        ...//code for reading data
        for (auto i = 0; i < colamount; i++)
            for (auto j = 0; j < rowamount; j++)
            {
                int x = j * dc + delt_x, y = i * dr + delt_y;
                cv::Mat subimg;
                std::cout << "ceilimg number:" << i * colamount + j << "\nceilimg pos:"  \
                    << x << " " << y << " " << dc << " " << dr << std::endl;
                srcimg(cv::Rect(x, y, dc, dr)).copyTo(subimg);
                QImage QsubImage = QImage((const unsigned char*)(subimg.data), subimg.cols, subimg.rows, QImage::Format_RGB888);
    
                view->addImage(QsubImage, j * QsubImage.width(), i * QsubImage.height());
            }
       }
    

    372667cd-d438-46c0-a664-4aff16fb794b-image.png

    A sub-image is about 3072 x 3840, you can clearly see that the lower part is incomplete display.

    THANK!


  • Qt Champions 2019

    @HereV said in How to solve the problem that qgrapics-related classes cannot display content Completely when the picture is huge(30000x40000):

    QImage QsubImage = QImage((const unsigned char*)(subimg.data), subimg.cols, subimg.rows, QImage::Format_RGB888);

    Please read the documentation: "The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer."



  • @Christian-Ehrlicher thanks,But that's not the reason you said , I found in a small demo that the graphics class doesn't limit the size of the content in the displayed scene, and the reason for the black area is that there is some problems in reading the file , thank you again for your help.



  • @HereV
    Nonetheless, as @Christian-Ehrlicher pointed out, you seem to have a local variable cv::Mat subimg; and you pass subimg.data to the QImage QsubImage you use in addImage(). That should leave the QImage pointing at data which has gone out of scope/been released. Then my understanding is you are "lucky" if that still works. You seem to be displaying multiple copies of the same image, have you tried your code with, say, different images in each position?


Log in to reply