user3561614
user3561614

Reputation: 1094

How to show a QImage without copying in QGraphicsScene

I have my own image class containing an unsigned char array with RGB values. I would like to show images stored in this class, without copying them, in a QGraphicsScene. I can make an QImage with

QImage image(data, width, height, width * 3, QImage::Format_RGB888);

without copying my image. How can I show image in a QGraphicsScene without a deep copy of data?

Upvotes: 0

Views: 1160

Answers (2)

With the default, raster paint engine/backend, the top-level widget's contents are stored as a QImage. Drawing a QImage (and a QPixmap, too) on it is quick and doesn't involve copies. The QPixmap, with the raster backend, is simply internally a QImage that has the same format as that of the backing store. The pixmap generally doesn't represent any native resource handle - since you are using a raster backend unless you ask for something else explicitly.

So what you would wish to do is to directly drawImage from your source image, within a QGraphicsItem::paint implementation. What really happens behind the scenes is the paint gets executed on the backing store - a QImage, and that's fast and efficient. The QPainter that you use operates on a QImage!

All you have to do is to implement a QGraphicsImageItem akin to QGraphicsPixmapItem. No copying and no format conversion will be involved as long as your source image has the same format as the image backing the top-level window. And how would you know that? Just ask the backing store about what format it's in.

QImage::Format backingStoreFormat(QWidget * widget) {
  auto store = dynamic_cast<QImage*>(widget->backingStore()->paintDevice())
  return store ? store->format() : QImage::Format_Invalid;
}

I leave the implementation of QGraphicsImageItem to the reader :)

Upvotes: 2

Valentin H
Valentin H

Reputation: 7458

For displaying images QPixmap is a proper class. QGraphicsScene pdovides a method only for a QPixmap.

QGraphicsPixmapItem * QGraphicsScene::addPixmap(const QPixmap & pixmap)

However, QPixmap is an optimized class for displaying images, so it can't be created with existing block of memory. So if you intend to display your memory data as an image in QGraphicsScene, it seems to be not possible (with reasonable effort).

Why do you concern about copying a data from your class into QPixmap? Is there a prove, that it will be a performance bottle-neck?

If not, either you convert your class directly to a QPixmap or use QPixmap::fromImage(). Add yout image with e.g.:

myScene->addPixmap( QPixmap::fromImage(myImage) );

Upvotes: 0

Related Questions