Discussion:
[Interest] Convertion between QImage to QPixmap taking to much time.
Celal SAVUR
2015-10-17 15:28:15 UTC
Permalink
Hello everyone,

I have some performance issue when I am using QPixmap.

I am getting image from buffer and I create QImage. After that using
QPixmap::fromImage(), creating pixmap and set it to QGraphicPixmapItem to
be drawn in scene.

When I put the timer to see how much time Qt spending to create QPixmap, I
realize that I converting from Qimage to QPixmap taking ~20 times more
time than crating Qimage from buffer.

By the way, I am getting image approximately every 200 ms some times faster
than that.

Do you have any suggestion to increase the performance?

Can I draw QImage into scene without Qpixmap convertion? How ?


Thank you.

Celal
Till Oliver Knoll
2015-10-17 20:03:02 UTC
Permalink
...
When I put the timer to see how much time Qt spending to create QPixmap, I realize that I converting from Qimage to QPixmap taking ~20 times more time than crating Qimage from buffer.
Yes, I guess that's perfectly possible. That depends off course on the original data layout and the native pixmap format of the target platform (btw what platform are we talking about?).

Bytes might need to be swizzled, padded, memory aligned etc.

You might try to directly load the raw data into a QPixmap, if all you want is to display the data anyway:

http://doc.qt.io/qt-5/qpixmap.html#loadFromData

You can try with different raw formats/byte ordering (if possible), to see whether that makes any difference in conversion time.

If all that fails try with OpenGL (textures).

Cheers,
Oliver
Celal SAVUR
2015-10-18 13:58:14 UTC
Permalink
Hi Oliver,

The system is linux OS. The original data is just vector of unsigned char
data, width and height and format. but format is not part of data it part
of struct. Therefore, I cannot use QPixmap.fromRawData();

I do not have any experience with openGL, If you can explain little bit ?






Celal SAVUR



On Sat, Oct 17, 2015 at 4:03 PM, Till Oliver Knoll <
Post by Celal SAVUR
...
When I put the timer to see how much time Qt spending to create QPixmap,
I realize that I converting from Qimage to QPixmap taking ~20 times more
time than crating Qimage from buffer.
Yes, I guess that's perfectly possible. That depends off course on the
original data layout and the native pixmap format of the target platform
(btw what platform are we talking about?).
Bytes might need to be swizzled, padded, memory aligned etc.
You might try to directly load the raw data into a QPixmap, if all you
http://doc.qt.io/qt-5/qpixmap.html#loadFromData
You can try with different raw formats/byte ordering (if possible), to see
whether that makes any difference in conversion time.
If all that fails try with OpenGL (textures).
Cheers,
Oliver
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Allan Sandfeld Jensen
2015-10-17 23:37:57 UTC
Permalink
Post by Celal SAVUR
Hello everyone,
I have some performance issue when I am using QPixmap.
I am getting image from buffer and I create QImage. After that using
QPixmap::fromImage(), creating pixmap and set it to QGraphicPixmapItem to
be drawn in scene.
When I put the timer to see how much time Qt spending to create QPixmap, I
realize that I converting from Qimage to QPixmap taking ~20 times more
time than crating Qimage from buffer.
By the way, I am getting image approximately every 200 ms some times faster
than that.
Do you have any suggestion to increase the performance?
You can convert a QImage into a QPixmap without image conversion by using the
flag Qt::NoImageConversion on QPixmap::fromImage. Note though that this means
the image will not be converted to an efficient type for painting to (which
pixmaps normally would be), but if you are only painting from it a few times
it might be more efficient overall.

`Allan
Gunnar Sletta
2015-10-19 11:00:22 UTC
Permalink
Post by Celal SAVUR
Hello everyone,
I have some performance issue when I am using QPixmap.
I am getting image from buffer and I create QImage. After that using QPixmap::fromImage(), creating pixmap and set it to QGraphicPixmapItem to be drawn in scene.
When I put the timer to see how much time Qt spending to create QPixmap, I realize that I converting from Qimage to QPixmap taking ~20 times more time than crating Qimage from buffer.
If you are using the QImage(uchar *data, int width, int height, ..) overload, this is surprising as creating the image from raw pixel data only has to allocate the QImage d-pointer and otherwise use the data as is.

Converting that to a QPixmap will entail a QImage::convertToFormat() to map the image into a system specific pixel format, usually QImage::RGB32 or QImage::ARGB32_Premultiplied, but any given QPA backend may override that with an other format if that is more compatible with its raster backingstore.
Post by Celal SAVUR
By the way, I am getting image approximately every 200 ms some times faster than that.
Do you have any suggestion to increase the performance?
Can I draw QImage into scene without Qpixmap convertion? How ?
There are a couple of options.

If you can provide the pixel data in a format compatible with the backingstore, the conversion can be simpler or just a no-op.

You can also draw the image directly using QPainter::drawImage(). If you didn't set the QGraphicsView viewport to be an OpenGL enabled viewport, then the image will be converted to the right format on the fly. The actual drawing will then be a bit slower, but as you avoid the conversion, it should be a net win.

You can do that by implementing your own QGraphicsItem and draw the image in the virtual paint() function.

If you have a GL viewport, then the image needs to be uploaded to a GL texture. QPainter will do this and put the image into some GL_RGB or GL_RGBA data and might perform additional conversion before that, but drawing the image using QPainter::drawImage might still result in less conversion.

Of course, if you have a GL viewport and some non-standard format, you can potentially speed it up further by implementing a QGraphicsItem which does raw GL, encapsulated by QPainter::beginNativePainting()/endNativePainting() and then upload to a texture of your choosing and then draw the texture with GL commands.

cheers,
Gunnar
Post by Celal SAVUR
Thank you.
Celal
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Gunnar Sletta
2015-10-19 11:09:38 UTC
Permalink
Post by Gunnar Sletta
Post by Celal SAVUR
Hello everyone,
I have some performance issue when I am using QPixmap.
I am getting image from buffer and I create QImage. After that using QPixmap::fromImage(), creating pixmap and set it to QGraphicPixmapItem to be drawn in scene.
When I put the timer to see how much time Qt spending to create QPixmap, I realize that I converting from Qimage to QPixmap taking ~20 times more time than crating Qimage from buffer.
If you are using the QImage(uchar *data, int width, int height, ..) overload, this is surprising as creating the image from raw pixel data only has to allocate the QImage d-pointer and otherwise use the data as is.
Converting that to a QPixmap will entail a QImage::convertToFormat() to map the image into a system specific pixel format, usually QImage::RGB32 or QImage::ARGB32_Premultiplied, but any given QPA backend may override that with an other format if that is more compatible with its raster backingstore.
Post by Celal SAVUR
By the way, I am getting image approximately every 200 ms some times faster than that.
Do you have any suggestion to increase the performance?
Can I draw QImage into scene without Qpixmap convertion? How ?
There are a couple of options.
If you can provide the pixel data in a format compatible with the backingstore, the conversion can be simpler or just a no-op.
You can also draw the image directly using QPainter::drawImage(). If you didn't set the QGraphicsView viewport to be an OpenGL enabled viewport, then the image will be converted to the right format on the fly. The actual drawing will then be a bit slower, but as you avoid the conversion, it should be a net win.
You can do that by implementing your own QGraphicsItem and draw the image in the virtual paint() function.
Bah.. Completely forgot about the Qt::NoImageConversion flag that Allan mentioned. That saves you going through QPainter::drawImage() and a bit of implementation work :)
Post by Gunnar Sletta
If you have a GL viewport, then the image needs to be uploaded to a GL texture. QPainter will do this and put the image into some GL_RGB or GL_RGBA data and might perform additional conversion before that, but drawing the image using QPainter::drawImage might still result in less conversion.
Of course, if you have a GL viewport and some non-standard format, you can potentially speed it up further by implementing a QGraphicsItem which does raw GL, encapsulated by QPainter::beginNativePainting()/endNativePainting() and then upload to a texture of your choosing and then draw the texture with GL commands.
cheers,
Gunnar
Post by Celal SAVUR
Thank you.
Celal
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Celal SAVUR
2015-10-20 19:32:02 UTC
Permalink
Thank you Allan and Gunnar,

I have tried the some of your method but no luck. When I used
Qt::NoFormatConversion flag. If I do not enable the openGL for my graphic
view, It does not draw a image and it just crash. but whenever I enable the
openGL, it draw but speed is same, in addition to that sometimes,
graphicview cannot draw all image, it just draw half of it and rest of
image is black.

I try also try to implement my own GraphicsItem but when I call
painter.drawimage(0,0, image); it crash. I could not figure out why It
crash. With same code, if I change drawimage to drawline, it works fine.


Do you think is a good to convert raw image data to a known format (XPM) on
fly and load to Qpixmap ? If yes , do you have any suggestion to do that.

thank you in advance.












Celal SAVUR
Post by Celal SAVUR
Post by Gunnar Sletta
Post by Celal SAVUR
Hello everyone,
I have some performance issue when I am using QPixmap.
I am getting image from buffer and I create QImage. After that using
QPixmap::fromImage(), creating pixmap and set it to QGraphicPixmapItem to
be drawn in scene.
Post by Gunnar Sletta
Post by Celal SAVUR
When I put the timer to see how much time Qt spending to create
QPixmap, I realize that I converting from Qimage to QPixmap taking ~20
times more time than crating Qimage from buffer.
Post by Gunnar Sletta
If you are using the QImage(uchar *data, int width, int height, ..)
overload, this is surprising as creating the image from raw pixel data only
has to allocate the QImage d-pointer and otherwise use the data as is.
Post by Gunnar Sletta
Converting that to a QPixmap will entail a QImage::convertToFormat() to
map the image into a system specific pixel format, usually QImage::RGB32 or
QImage::ARGB32_Premultiplied, but any given QPA backend may override that
with an other format if that is more compatible with its raster
backingstore.
Post by Gunnar Sletta
Post by Celal SAVUR
By the way, I am getting image approximately every 200 ms some times
faster than that.
Post by Gunnar Sletta
Post by Celal SAVUR
Do you have any suggestion to increase the performance?
Can I draw QImage into scene without Qpixmap convertion? How ?
There are a couple of options.
If you can provide the pixel data in a format compatible with the
backingstore, the conversion can be simpler or just a no-op.
Post by Gunnar Sletta
You can also draw the image directly using QPainter::drawImage(). If you
didn't set the QGraphicsView viewport to be an OpenGL enabled viewport,
then the image will be converted to the right format on the fly. The actual
drawing will then be a bit slower, but as you avoid the conversion, it
should be a net win.
Post by Gunnar Sletta
You can do that by implementing your own QGraphicsItem and draw the
image in the virtual paint() function.
Bah.. Completely forgot about the Qt::NoImageConversion flag that Allan
mentioned. That saves you going through QPainter::drawImage() and a bit of
implementation work :)
Post by Gunnar Sletta
If you have a GL viewport, then the image needs to be uploaded to a GL
texture. QPainter will do this and put the image into some GL_RGB or
GL_RGBA data and might perform additional conversion before that, but
drawing the image using QPainter::drawImage might still result in less
conversion.
Post by Gunnar Sletta
Of course, if you have a GL viewport and some non-standard format, you
can potentially speed it up further by implementing a QGraphicsItem which
does raw GL, encapsulated by
QPainter::beginNativePainting()/endNativePainting() and then upload to a
texture of your choosing and then draw the texture with GL commands.
Post by Gunnar Sletta
cheers,
Gunnar
Post by Celal SAVUR
Thank you.
Celal
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Gunnar Sletta
2015-10-21 09:27:05 UTC
Permalink
You construct your QImage from a uchar* right? This constructor does not take a deep copy of the image data you pass in, it just stores it. That means that if you for some reason delete the source data before Qt takes it into use (which happens typically on the next paint cycle or in your custom graphics item), you will have a dangling pointer in the QImage you are drawing and that will typically crash.

cheers,
Gunnar
Post by Celal SAVUR
Thank you Allan and Gunnar,
I have tried the some of your method but no luck. When I used Qt::NoFormatConversion flag. If I do not enable the openGL for my graphic view, It does not draw a image and it just crash. but whenever I enable the openGL, it draw but speed is same, in addition to that sometimes, graphicview cannot draw all image, it just draw half of it and rest of image is black.
I try also try to implement my own GraphicsItem but when I call painter.drawimage(0,0, image); it crash. I could not figure out why It crash. With same code, if I change drawimage to drawline, it works fine.
Do you think is a good to convert raw image data to a known format (XPM) on fly and load to Qpixmap ? If yes , do you have any suggestion to do that.
thank you in advance.
Celal SAVUR
Post by Gunnar Sletta
Post by Celal SAVUR
Hello everyone,
I have some performance issue when I am using QPixmap.
I am getting image from buffer and I create QImage. After that using QPixmap::fromImage(), creating pixmap and set it to QGraphicPixmapItem to be drawn in scene.
When I put the timer to see how much time Qt spending to create QPixmap, I realize that I converting from Qimage to QPixmap taking ~20 times more time than crating Qimage from buffer.
If you are using the QImage(uchar *data, int width, int height, ..) overload, this is surprising as creating the image from raw pixel data only has to allocate the QImage d-pointer and otherwise use the data as is.
Converting that to a QPixmap will entail a QImage::convertToFormat() to map the image into a system specific pixel format, usually QImage::RGB32 or QImage::ARGB32_Premultiplied, but any given QPA backend may override that with an other format if that is more compatible with its raster backingstore.
Post by Celal SAVUR
By the way, I am getting image approximately every 200 ms some times faster than that.
Do you have any suggestion to increase the performance?
Can I draw QImage into scene without Qpixmap convertion? How ?
There are a couple of options.
If you can provide the pixel data in a format compatible with the backingstore, the conversion can be simpler or just a no-op.
You can also draw the image directly using QPainter::drawImage(). If you didn't set the QGraphicsView viewport to be an OpenGL enabled viewport, then the image will be converted to the right format on the fly. The actual drawing will then be a bit slower, but as you avoid the conversion, it should be a net win.
You can do that by implementing your own QGraphicsItem and draw the image in the virtual paint() function.
Bah.. Completely forgot about the Qt::NoImageConversion flag that Allan mentioned. That saves you going through QPainter::drawImage() and a bit of implementation work :)
Post by Gunnar Sletta
If you have a GL viewport, then the image needs to be uploaded to a GL texture. QPainter will do this and put the image into some GL_RGB or GL_RGBA data and might perform additional conversion before that, but drawing the image using QPainter::drawImage might still result in less conversion.
Of course, if you have a GL viewport and some non-standard format, you can potentially speed it up further by implementing a QGraphicsItem which does raw GL, encapsulated by QPainter::beginNativePainting()/endNativePainting() and then upload to a texture of your choosing and then draw the texture with GL commands.
cheers,
Gunnar
Post by Celal SAVUR
Thank you.
Celal
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Loading...