PDA

View Full Version : CPU intensive QPainter



jcarneiro
20th October 2010, 11:37
Hi all,

I am new to QT, and for reference am using QT4.
I intend to draw points in an image of 255 x 255 in realtime.

To draw the points (number of points variable), I do:


QColor b(0,0,255,255);
QPainter p(&pixmap);
p.setPen(b);
p.drawPoint(y, x);
p.drawPoint(y, x);
p.drawPoint(y, x);
p.drawPoint(y, x);
p.drawPoint(y, x);
...
p.drawPoint(y, x);
p.drawPoint(y, x);



I am using a label to show the image where I just do


label->setPixmap(pixmap)


Every 40ms I erase the image to restart drawing new image of points with:


QPainter p(pixmap);
p.eraseRect(0,0, 255, 255);


Everything is working fine, but...
First, I would like to know if this is the correct way of creating/showing image of points or if there is a better approach.
Second, this appears to be very CPU intensive, is there a problem with this code? Should I be using something different instead of QPainter and pixmap? I get up to 80% CPU usage on core2duo 2,53GHz. Thus unacceptable for such a simple program.
Third, intend to do this for maybe 3 or more images at the same time so not only is unacceptable but becomes impossible...

Thank you in advance for any help,

Regards

wysota
20th October 2010, 12:06
So how many points are you drawing in one go?

jcarneiro
20th October 2010, 12:26
Hi,

The number of points is variable, theoretically would be between 1 and all (255 x 255 = 65025)
But I guess I never even do more than 200.

wysota
20th October 2010, 12:44
Try using QPainter::drawPoints(), it should be much faster than calling drawPoint() a number of times. if it's still not enough, perform drawing on QImage instead of QPixmap but not using the painter API but rather by retrieving the pixel data (QImage::bits()) and manipulating the pixels directly. Then convert the image back to a pixmap. You can even manipulate the image in a separate thread if your machine is multicore. Also consider limiting your frame rate - if you erase the pixmap every 40ms it means you are doing that 25 times per second which is more than your eye can actually understand. You can halve the rate without making the user experience worse.

jcarneiro
20th October 2010, 15:08
Thanks a lot,

Indeed using drawpoints method is extremely faster.
Wanted to try the other approach but didn't quite manage to do it, seems like I'm getting some random data.
To show the image I am doing:


QImage tmp(Imagebits, 255, 255, QImage::Format_Mono);
QPixmap pixMap = QPixmap::fromImage(tmp);
ui->label->setPixmap(pixMap);


to clear the image I am using:


QImage tmp(Imagebits, 255, 255, QImage::Format_Mono);
tmp.fill(0);
Imagebits = tmp.bits();


without changing any bit in the array I am already getting random data.
By the way, thinking on how to access the array, method bits returns an uchar* does. It allocate a fixed size for all format or it is format dependent and in case mono pixels 0 - 7 are in first position etc?

Regarding the frame rate/erase redraw frequency it's true and a very good idea although I am acquiring data much faster and drawing real-time into pixmap (the 40 ms was more for context :)). Even if I don't draw anything onscreen, just writing with drawpoint onto pixmap is very slow.