PDA

View Full Version : How can I use concurrency to generate an QImage



lni
30th August 2011, 09:14
Hi,

I need to generate an QImage repeatedly from data using following code. How can I use QtConcurrent to take advantage of multi-cores computer?

Thanks!



QImage toImage( QVector<const float*> data, int width, int height )
{
QImage image( width, height, QImage::Format_ARGB32 );

for ( int iy = 0; iy < image.height(); iy++ ) {
for ( int ix = 0; ix < image.width(); ix++ ) {
QRgb rgb = calcRbgFromSomewhere( data[ ix ][ iy ] );
image.setPixel( ix, iy, pixel );
}
}
return image;
}

JohannesMunk
30th August 2011, 14:30
Hi!

Yeah.. the docs on the QtConcurrent stuff are really poor!

What you could do is store your float data together with the width and height value together in a small class, like so:



class FloatImage
{
public:
FloatImage(QVector<const float*> data, int width, int height) : data(data),width(width),height(height) {}
QVector<const float*> data;
int width;
int height;
QImage toImage()
{
// Your code..
}
};
You can call this with QtConcurrent::run



FloatImage fi(yourData,200,100);
QFutureSynchronizer<QImage> synchronizer;
synchronizer.addFuture( QtConcurrent::run(fi,&FloatImage::toImage));
...
synchronizer.waitForFinished();


This shows how to wait for multiple operations with QFutureSynchronizer!

HIH

Johannes

wysota
30th August 2011, 14:44
But this way you will only use one core. It's better to use the "map" semantics and let every pixel or scanline be processed by a different thread.
For instance:

QImage img(640,480);
struct Elem {
uchar *scanLine;
int lineIndex;
int lineSize;
};

void func(Elem &e) {
for(int i=0;i<e.lineSize;++i){
QRgb rgb = calc(i, e.lineIndex);
e.scanLine[i] = rgb; // or something like this
}
}

QList<Elem> image;
for(int i=0;i<img.height();++i){
Elem e;
e.scanLine = img.scanLine(i);
e.lineIndex = i;
e.lineSize = img.width();
}
QtConcurrent::blockingMap(image, func);

JohannesMunk
30th August 2011, 14:49
Hello wysota!

I understood lni as if he had multiple images to process. For that he only would need to call QtConcurrent:run multiple times with his different images. I tried to indicate that with "..."

But now he has examples for both granularities!

I think "image.append(e);" is missing after line 20 in your code.

Cheers,

Joh

wysota
30th August 2011, 16:06
Yes, of course, there is a missing line in my code.

lni
31st August 2011, 00:51
Thank you all!! I will try that.