显示连续QImages流的有效方式

时间:2014-03-12 13:29:47

标签: qt

我目前正在使用QLabel执行此操作,但这似乎相当缓慢:

void Widget::sl_updateLiveStreamLabel(spImageHolder_t _imageHolderShPtr) //slot
{
    QImage * imgPtr = _imageHolderShPtr->getImagePtr();
    m_liveStreamLabel.setPixmap( QPixmap::fromImage(*imgPtr).scaled(this->size(), Qt::KeepAspectRatio, Qt::FastTransformation) );
    m_liveStreamLabel.adjustSize();
}

这里我为每个到达的新图像生成一个新的QPixmap对象。由于QPixmap操作仅限于GUI线程,这也会使GUI感觉响应不佳 我已经看到已经有一些关于这方面的讨论了,他们中的大多数建议使用QGraphicsView或QGLWidget,但是我还没有找到一个如何正确使用它们的快速示例,这将是我正在寻找的。
我很感激任何帮助。

3 个答案:

答案 0 :(得分:3)

QPixmap::fromImage不是唯一的问题。还应避免使用QPixmap::scaledQImage::scaled。但是,您无法直接在QImageQLabel中显示QGraphicsView。这是我的班级直接显示QImage并将其缩放到小部件的大小:

部首:

class ImageDisplay : public QWidget {
  Q_OBJECT
public:
  ImageDisplay(QWidget* parent = 0);
  void setImage(QImage* image);

private:
  QImage* m_image;

protected:
  void paintEvent(QPaintEvent* event);

};

来源:

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());
}

我在缩小到600x600尺寸的3000x3000图像上进行了测试。它提供40 FPS,而QLabelQGraphicsView(即使启用了快速图像转换)也可提供15 FPS。

答案 1 :(得分:1)

设置QGraphicsView和QGraphicsScene非常简单: -

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();
}

答案 2 :(得分:0)

我建议不要使用QLabel,而是编写自己的类。 setPixmap的每次调用都会导致布局系统重新计算项目的大小,这可以传播到最顶层的父项(QMainWindow),这是非常大的开销。

转换和缩放也有点贵。

最后,最好的方法是使用分析器来检测最大问题在哪里。