Efficient way of displaying a continuous stream of QImages

后端 未结 3 560
故里飘歌
故里飘歌 2020-12-16 06:47

I am currently using a QLabel to do this, but this seems to be rather slow:

void Widget::sl_updateLiveStreamLabel(spImageHolder_t _imageHolderShPtr) //slot         


        
相关标签:
3条回答
  • 2020-12-16 06:47

    QPixmap::fromImage is not the only problem. Using QPixmap::scaled or QImage::scaled also should be avoided. However you can't display QImage directly in QLabel or QGraphicsView. Here is my class that display QImage directly and scales it to the size of the widget:

    Header:

    class ImageDisplay : public QWidget {
      Q_OBJECT
    public:
      ImageDisplay(QWidget* parent = 0);
      void setImage(QImage* image);
    
    private:
      QImage* m_image;
    
    protected:
      void paintEvent(QPaintEvent* event);
    
    };
    

    Source:

    ImageDisplay::ImageDisplay(QWidget *parent) : QWidget(parent) {
      m_image = 0;
      setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    }
    
    void ImageDisplay::setImage(QImage *image) {
      m_image = image;
      repaint();
    }
    
    void ImageDisplay::paintEvent(QPaintEvent*) {
      if (!m_image) { return; }
      QPainter painter(this);
      painter.drawImage(rect(), *m_image, m_image->rect());
    }
    

    I tested it on 3000x3000 image scaled down to 600x600 size. It gives 40 FPS, while QLabel and QGraphicsView (even with fast image transformation enabled) gives 15 FPS.

    0 讨论(0)
  • 2020-12-16 06:57

    Setting up a QGraphicsView and QGraphicsScene is quite straight-forward: -

    int main( int argc, char **argv )
    {
        QApplication app(argc, argv);
    
        // Create the scene and set its dimensions
        QGraphicsScene scene;
        scene.setSceneRect( 0.0, 0.0, 400.0, 400.0 );
    
        // create an item that will hold an image
        QGraphicsPixmapItem *item = new QGraphicsPixmapItem(0);
    
        // load an image and set it to the pixmapItem
        QPixmap pixmap("pathToImage.png") // example filename pathToImage.png
        item->setPixmap(pixmap);
    
        // add the item to the scene
        scene.addItem(item);
    
        item->setPos(200,200); // set the item's position in the scene
    
        // create a view to look into the scene
        QGraphicsView view( &scene );
        view.setRenderHints( QPainter::Antialiasing );
        view.show();
    
        return app.exec();
    }
    
    0 讨论(0)
  • 2020-12-16 07:00

    I recommend not use QLabel but write own class. Every call of setPixmap causes layout system to recalculate sizes of items and this can propagate to topmost parent (QMainWindow) and this is quite big overhead.

    Conversion and scaling also is a bit costly.

    Finally best approach is to use profiler to detect where is the biggest problem.

    0 讨论(0)
提交回复
热议问题