PDA

View Full Version : Fast way to display 800*600 changing pixels



Zooky
2nd January 2013, 15:25
Hello,

I'm new to Qt and have to display images of approximately 600*800 pixels. The color of each pixel is calculated independently of the others and has to be constantly recalculated. I made a loop through the pixels to build a QImage (which is, according to the doc, optimised for pixel operations), which is converted in a Pixmap and displayed in a QLabel. However, the conversion operation is to slow.
I searched on the forums and found many different ways to display images, but I don't know which one is the best for my situation. For example, could I use QGraphicScene/QGraphicView to do it ? Does the fact that I calculate every pixel lead to an other solution ?
I know nothing about openGL, but would the use of a QGLWidget be a good thing ?

Please help me, I'm a bit lost with all the different possibilities that I found.

(And please excuse my english, which is not very good)

Santosh Reddy
3rd January 2013, 07:12
As you are dealing with just one image, which ever widget you use QGraphicsView/QWidget/opengl may not differ much.

I see the bottleneck is with recalculating pixel values, displaying them is not. Selection of a widget will not help you in recalculating the pixels faster.

wysota
3rd January 2013, 09:25
Transforming QImage to QPixmap is always going to be slow on X11. See if running your app with a "-graphicssystem render" option helps. One way or the other it might prove faster to draw each pixel separately instead of redrawing the whole image unless all pixels change at the same time (then rendering the whole image will always be faster than plotting 800x600 separate entities). Using OpenGL could help too but you need to manipulate textures directly (e.g. by using FBOs).

Zooky
3rd January 2013, 09:31
Thanks for reply !

As the calculation of the color is really simple, I thought that the problem was the conversion, but maybe I was false. I will try to improve this calculation.
But why does the fact that I have only one image to display impact the choice of the widget ? I mean, recalculating the pixels all the time is really technically different than displaying different images ?

wysota
3rd January 2013, 10:43
One image that is 800x600 in size can be represented as four images 400x300 each or sixteen images 200x150 each. If only some pixels change at a time then redrawing one 200x150 image is faster than redrawing one 800x600 image. Transforming 200x150 from QImage to QPixmap is also much faster than doing the same for a 800x600 image. The thing is to do only what really needs to be done. For instance you said that pixel values are "constantly recalculated". There is no such thing with computers as "constant recalculation" as time in computers is discrete. You can probably get away with recalculating values once per second or twice per second or maybe 10 times per second. But if you "constantly" recalculate then your machine won't have time for anything else (including refreshing your UI or even updating time on your system clock).

Zooky
3rd January 2013, 11:56
Yes, of course pixels are not constantly recalculated, sorry for that. I just meant that I have to frequently recalculate them (because I think it would implie to have a different approach than if I had to display one image a unique time). In my case, I'm representing a scene with different objects. I would like to implement deplacements in this scene, that means having many images per second, and all pixels changing at the same time. And actually, when I recalculate the all image, it takes ~1 second. But maybe this is just incompatible with the way I'm calculating colors.
Thank's for helping !

wysota
3rd January 2013, 12:23
You are again using terms like "many", "the same time", etc. This doesn't mean anything. There are different solutions for different problems so you have to clearly define your problem to find a good solution. The fact that you think that all pixels change "at the same time" doesn't mean that all pixels change their values and that it needs to happen at the same time. If you divide your image into tiles and process each tile separately in a worker thread (e.g. using QtConcurrent or a QThread) then you can update one tile on the screen while other ones are still being processed. You will get a slight delay before tiles are updated but an average delay will be much smaller than processing and updating the whole big image in one go. If that's not acceptable then you can process everything in the worker thread and just render the result to the screen in main thread while the next frame is calculating. Or you can calculate each pixel separately as the needed data comes in and update that pixel only. Or... use one of many other possible approaches that heavily depend on the task you are performing.

Zooky
3rd January 2013, 13:43
Ok, sorry if I was not clear. I used "all pixels change at the same time" to mean that a significative part of them will change between to consecutive images (as there is some continuity between pixels, it's better to calculate the value of all pixels and display them in one time). That is still not very clear, I know it, but of course it depends of the scene that I am rendering. But the point is that even if some pixels keep the same color between two images, the only way to know it is to recalculate and compare.
The idee of using multiple threads is probably a good one, I will try to implement it.

Thanks.

wysota
3rd January 2013, 15:58
But the point is that even if some pixels keep the same color between two images, the only way to know it is to recalculate and compare.

That doesn't have to be true. I don't know what you are doing exactly but maybe the changes only happen in some local neighbourhood that can be precalculated. Confining changes to a sub-rect of the image already allows you to do some optimisations.