PDA

View Full Version : QImage from 8 bit char* RGB buffer



tboloo
15th April 2006, 14:43
This is my first post so hello to everybody :)
I't trying to create qt app which will display images from 8 bit RGB buffer.
I tried warious ways to achiewe it, but so far without success. Here is what I've tried :

...
QImage img;
img.loadFromData( (uchar*)myRBGBuffer );
QPixmap pixmap;
pixmap.convertFromImage(img);
...

but this gives me incorrect results - whole pixmap is in one color.
The I tried adding PPM header - "P6 width height nColors", but that did't help also.

My question is - how can I display images from RGB buffer, as fast as possible, avoiding unnecessary conversions - I'm trying to create mobile robot driver ap, so time is crucial.

wysota
15th April 2006, 14:54
You need to set a palette (color mapping table) for the image.

From QImage docs:

8-bpp images are much easier to work with than 1-bpp images because they have a single byte per pixel:
QImage image;
// set entry 19 in the color table to yellow
image.setColor( 19, qRgb(255,255,0) );
// set 8 bit pixel at (x,y) to value yellow (in color table)
*(image.scanLine(y) + x) = 19;

tboloo
15th April 2006, 15:52
Thanks for reply. Unfortunatelly it did't help.Here is my code:
...
imgData = cvLoadImage( s, -1 ); //function that loads image
QImage img;
img.create( imgData->width, imgData->height, 8, 255 );
for ( int i=0; i<255; i++ ) // build color table
img.setColor( i, qRgb(i,0,0) );
img.loadFromData( (uchar*)imgData->imageData, imgData->widthStep*imgData->height, 0 );
QPixmap pixmap;
pixmap.convertFromImage(img);
m_pixmap->setPixmap(pixmap);
...
but the displayed pixmap is black :(

wysota
15th April 2006, 16:04
Check if the QImage object is ok (for example by saving it to file and viewing with an image viewer).

tboloo
15th April 2006, 17:13
Check if the QImage object is ok (for example by saving it to file and viewing with an image viewer).
Unfortunatelly it isn't :(
The rgb data is ok, since I can save using opencv library (which I'm using to do some image processing), but I can't construct proper qimage from it ...

jacek
15th April 2006, 17:16
QImage::fromData() expects data in a format like BMP or PNG, not just an array of colours.

Try:
QImage img;
img.create( imgData->width, imgData->height, 8 );
for ( int i = 0; i < imgData->width; ++i ) {
for ( int j = 0; j < imgData->height; ++j ) {
img.setPixel( i, j, ... );
}
}
m_pixmap->setPixmap( img );

tboloo
15th April 2006, 17:29
QImage::fromData() expects data in a format like BMP or PNG, not just an array of colours.

Try:
QImage img;
img.create( imgData->width, imgData->height, 8 );
for ( int i = 0; i < imgData->width; ++i ) {
for ( int j = 0; j < imgData->height; ++j ) {
img.setPixel( i, j, ... );
}
}
m_pixmap->setPixmap( img );
I know about it, but I have to do some processing and then show images as fast as possible therefore coping image data pixel by pixel isn't something that I want. I'm hoping to achieve ~25fps (with some processing included).Surely it is possible with qt, isn't it ?

jacek
15th April 2006, 18:45
therefore coping image data pixel by pixel isn't something that I want. I'm hoping to achieve ~25fps (with some processing included).
It depends how on the way you store that image data. If all pixels are in one block and their representation is compatible with QRgb, you could use qmemmove instead.

http://www.qtcentre.org/forum/showthread.php?t=164

wysota
15th April 2006, 18:47
If you want to do 25fps, avoid converting between a QImage and QPixmap (which is said to be slow). It's better to blit the image directly without conversion.

tboloo
15th April 2006, 20:01
I've updated code to

imgData = cvLoadImage( s, -1 );
cvSaveImage("cvImage.png",imgData );
QImage img;
img.create( imgData->width, imgData->height, 8, 255 );
unsigned char *buff = img.bits();
memcpy(buff,(uchar*)imgData->imageData,
imgData->widthStep*imgData->height);
for ( int i=0; i<255; i++ ) // build color table
img.setColor( i, qRgb(i,0,0) );
img.save( "qtimage", "PNG", 0 );
QPixmap pixmap;
pixmap.convertFromImage(img);
m_pixmap->setPixmap(pixmap);
but result is somehow far from what I expect ;)
This is the orginal that I try to load cvimage.png (http://btekielski.googlepages.com/cvimage.png)
and this is the result qtimage.png (http://btekielski.googlepages.com/qtimage.png)

wysota
15th April 2006, 20:08
If you'd set appropriate colours, it would be easier to see what's wrong. At least make them gray ( img.setColor( i, qRgb(i,i,i) ); ).

tboloo
15th April 2006, 20:18
If you'd set appropriate colours, it would be easier to see what's wrong. At least make them gray ( img.setColor( i, qRgb(i,i,i) ); ).
I doesn't change much :( , it just becomes gray instead of red, see qtimage_gray.png (http://btekielski.googlepages.com/qtimage_gray.png)
Conserning your previous post I'll try another approaches as soon as I'll get images displayed correctly.

wysota
15th April 2006, 20:23
Well, that's much better :)

My guess is that this cv holds data in some other order than QImage expects. The image is interlaced and each second scanline is translated to the right.

tboloo
15th April 2006, 20:56
Well, that's much better :)

My guess is that this cv holds data in some other order than QImage expects. The image is interlaced and each second scanline is translated to the right.
I guess you're right. I think I'll have to play with scanLine() function, althoug I'm not sure whether I'll be able to do all necessary stuff in less then 40ms :( .
Anyway thanks for your help and quick response.