PDA

View Full Version : Converting from RGB24 to RGB32



mahiapkum
26th May 2008, 08:47
I have an application which captures video with 24 bit depth and when i try to display it using QImage which uses 32 bit depth,image is not displayed properly.When i make video capture to 32 bits depth the image is displayed with good quality.Is there a means by which i can use 24 bit in Qt, m using Qt 3.3 version which only supports 32 bits.My vidoe codec works for 24 bits only.

ChristianEhrlicher
26th May 2008, 09:00
What do you mean by 'not displayed correctly' ?
24Bit RGB is the same like 32Bit ARGB with alpha set to 0.

mahiapkum
26th May 2008, 09:37
In the sense when i display it using QImage i get a carbon kind of image being displayed.Is there a means by which i can convert from 24 bit to 32 bit and display in Qt.

ChristianEhrlicher
26th May 2008, 09:40
Then your incoming format is maybe not RGB.
Create a QImage and set every pixel with setPixel() (http://doc.trolltech.com/3.3/qimage.html#setPixel).

mahiapkum
26th May 2008, 10:40
Let me explain..I have a webcam which can capture both at 24 and 32 bit depth.I get the captured image buffer pointer and i send this buffer to QImage and set the widget with this image.Qt 3.3 supports 32 bit depth but the codec i am using is for 24 bits which when encoded and decoded gives me a 24 bit Image and since QImage supports 32 bit image i am not able to display the decoded 24 bit Image properly as i mentioned earlier.The image buffer i am getting from the camera is in RGB format only.I know that 32 bit depth is ARGB data with alpha set to 0,hence i want to know is there a means by which i can convert this 24 bit RGB data into 32 bit ARGB data either in Qt or any other source.Thanks in advance.

ChristianEhrlicher
26th May 2008, 10:43
I already said this - read your RGB data and put it into a QImage with setPixel() ... what else do you need??

pherthyl
26th May 2008, 19:10
Don't use setPixel. It's very slow. Have a look here for some hints on how to do it: http://www.qtcentre.org/forum/f-qt-programming-2/t-qimage-data-via-ffmpeg-9935.html/?highlight=ffmpeg
and this might be use useful (example code using OpenCV to capture from webcams)
http://www.qtcentre.org/forum/f-qt-programming-2/t-opencv-integration-11655.html/?highlight=ffmpeg

spud
27th May 2008, 09:46
If you want to roll your own, you could use the following code:


int w=..., h=...;
uchar* input=...;

QImage img(w, h, QImage::Format_RGB32);
for (int y=0;y<h;y++)
{
QRgb* line = img.scanLine(y);
for (int x=0;x<w;x++)
*(line++) = qRgb(input[y*w + 3*x], input[y*w + 3*x+1], input[y*w + 3*x+2]);
}

This won't be painfully slow like using setPixel(), but it will never be as fast as using optimized libraries like OpenCV either.

mahiapkum
28th May 2008, 14:22
Thanks for your advice, but i would like to show my code so that u get my problem:
here is the code which captures image from the webcam:


static struct video_mmap vm;
mmap_test(int i)
{
vm.format = VIDEO_PALETTE_RGB32;
vm.frame = 0;
vm.width = 176;
vm.height = 144;
ioctl(device_fd, VIDIOCMCAPTURE, &vm);
ioctl(device_fd, VIDIOCSYNC, &numframe);
return buffer;
}

when video format is VIDEO_PALETTE_RGB32 the display code displays good quality image.

here is the display code:


display()
{
img = new QImage;
img->create(176, 144, 32, 0, QImage::IgnoreEndian);
raw_buf = mmap_test(0); //this gets the Image buffer
memcpy(img->bits(), raw_buf, 101376); //101376 is width*height*32 bits is 4 chars 176*144*4
paint.drawImage(0, 0, *img, 0, 0, -1, -1);
}

but when i change format = VIDEO_PALETTE_RGB24 i get a carbon kind of image.I want to know is there a problem in the capture or the QImage does not support VIDEO_PALETTE_RGB24 format.If it doesnt is there any other alternate way to do this.

pherthyl
28th May 2008, 17:56
We just explained how to do exactly that. Choose a method that you like.

You can't copy directly because the image formats are different. QImage expects 32bit format. If you're copying from 24bit source then you need to use one of the methods that was posted.

mahiapkum
30th May 2008, 07:37
Thanks for your advice and i have done exactly what has been mentioned by copying individual pixels.Here is the code:


for (int y=0;y<h;y++)
{
QRgb* line = (QRgb*)img.scanLine(y);
for (int x=0;x<w;x++)
*(line++) = qRgb(input[y*w + 3*x], input[y*w + 3*x+1], input[y*w + 3*x+2]);
}
status = pix.convertFromImage(img, Qt::ColorOnly);
paint.drawPixmap(0, 0, pix, 0, 0, -1, -1);

Now am i displaying the image correctly???After copying the individual pixels into the image,first i convert it into pixmap and than draw it using QPainter.

spud
30th May 2008, 14:08
Now am i displaying the image correctly???
Well, what do you see? Your code seems correct.
You might want to split up the conversion and rendering into different routines, since you only need to convert once, but you might have to paint multiple times.

pherthyl
30th May 2008, 16:24
Looks about right to me. You can use drawImage directly so you dont have to convert (although the conversion happens implicitly anyway).

high_flyer
2nd June 2008, 11:55
You might have a problem with "endianess" (big endian (MSB first) or little endian (LSB first)), RGB vs BGR or similar problem.
Make sure you know exactly which format your image is, and then adjust the above suggested code.
Have a look at image formats here:
http://doc.trolltech.com/4.3/qimage.html#image-formats

mahiapkum
2nd June 2008, 13:08
I am using Qt 3.3 version and to have an endian problem the image data which i get is an unsigned char and i copy the image also as an unsigned char itself.