在“等效”QPixmap上绘制QGraphicItems的最快方法

时间:2012-11-17 15:49:41

标签: c++ qt graphics

我想绘制彩色瓷砖作为QGraphicsscene的背景,并使用QGraphicsView为场景提供平移和缩放功能。首先,我使用QGraphicItems绘制每个图块。由于我有很多瓷砖,这在平移或缩放时是一个相当大的性能问题,但由于我之后不需要修改瓷砖的任何部分,我转而使用以下代码生成QPixmap:

void plotGrid(){
    Plotable::GraphicItems items;
    append(items,mParticleFilter.createGridGraphics());
    append(items,mParticleFilter.getRoi().mRectangle.createGraphics(greenPen()));
    scaleItems(items,1.0,-1.0);
    QGraphicsScene scene;
    showItemsOnScene(items,&scene);
    QRectF boundingRect = scene.itemsBoundingRect();
    double cScale = ceil(1920.0/boundingRect.size().width());
    QSize size(boundingRect.size().toSize()*cScale);
    QPixmap pixmap(size);
    pixmap.fill(Qt::transparent);
    QPainter p(&pixmap);
    //p.setRenderHint(QPainter::Antialiasing);
    scene.render(&p);
    p.end();
    QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pixmap);
    item->setOffset(boundingRect.topLeft()*cScale);
    item->scale(1/cScale,1/cScale);
    mpView->showOnScene(item);
  }

虽然这解决了缩放和平移问题,但生成像素图的时间会引入一些显着的延迟,可能是因为我首先创建一个场景然后渲染它。从QGraphicItem开始,是否有更快的方式来生成QPixmap?

为了完整性,我们会对图片进行处理:enter image description here

1 个答案:

答案 0 :(得分:0)

所以我终于至少使用了一个中间场景。以下代码仅依赖于QPainter来渲染像素图。我的主要问题是让所有变换都正确。否则它很直接...... 在我的方案中,此版本将处理时间减半至500毫秒。 450毫秒花在绘画项目上。如果有人有更多改进的建议,那将是非常受欢迎的(顺便说一句,解决方案并没有多大帮助)

void SceneWidget::showAsPixmap(Plotable::GraphicItems const& items){
    QRectF boundingRect;
    boostForeach(QGraphicsItem* pItem,items) {
      boundingRect = boundingRect.united(pItem->boundingRect());
    }
    QSize size(boundingRect.size().toSize());
    double const cMaxRes =1920;
    double const scale = cMaxRes/boundingRect.size().width();
    QPixmap pixmap(size*scale);
    pixmap.fill(Qt::transparent);
    QPainter p(&pixmap);
    //p.setCompositionMode( QPainter::CompositionMode_Source );
    p.translate(-boundingRect.topLeft()*scale);
    p.scale(scale,scale);
    QStyleOptionGraphicsItem opt;
    boostForeach(QGraphicsItem* item,items) {
      item->paint(&p, &opt, 0);
    }
    p.end();
    QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pixmap);
    item->scale(1.0/scale,-1.0/scale);
    item->setOffset(boundingRect.topLeft()*scale);
    showOnScene(item);
}