PDA

View Full Version : Copy a MemBuffer to a QPixmap



MangoCats
January 6, 2010, 21:54:20
Hi,

Is anyone integrating IC Imaging Controls with Qt? I think I have almost everything I need to make it work, except, I'd really like a nice function to convert a MemBuffer to a QPixmap - efficiently (for later drawing to a QGLWidget...)

Any thoughts or suggestions would be welcome...

MangoCats
January 7, 2010, 02:24:57
What I have done for now is move to a QImage instead of a QPixmap, with this kind of implementation:

ICImage::ICImage( int w, int h ) : QImage(QSize(w,h),QImage::Format_RGB32)

bool ICImage::loadMemBuffer( smart_ptr<MemBuffer> mb )
{ int w = mb->getSize().cx;
int h = mb->getSize().cy;
if (( width() != w ) || ( height() != h ))
{ videoWidget->emitChangeImageSize( w, h );
return false;
}
// Do the data copy (invert image)
int row_size = mb->getBufferSize() / h;
uchar *imp = this->bits();
BYTE *mbp = mb->getPtr() + mb->getBufferSize() - row_size;
for ( int i = 0 ; i < h ; i++ )
{ memcpy( imp, mbp, row_size );
imp += row_size;
mbp -= row_size;
}
return true;
}

Again, if there is a better way, I'd love to hear about it.

Stefan Geissler
January 7, 2010, 08:52:58
Hi,

If you need to flip the image horizontal, then your source code is the fastest method. In case you want to use the IC RotateFlip filter for flipping the image, then you can shorten your copy function:



bool ICImage::loadMemBuffer2( smart_ptr<MemBuffer> mb )
{
int w = mb->getSize().cx;
int h = mb->getSize().cy;
if (( width() != w ) || ( height() != h ))
{
videoWidget->emitChangeImageSize( w, h );
return false;
}
mb->Lock(); // Prevent the buffer from being overwritten.
// Unlock the buffer later again.
uchar *imp = this->bits();
imp = mb->getPtr();
return true;
}

Please keep in mind, I have no knowledge about the QT images.

MangoCats
January 7, 2010, 14:59:37
Thanks,

When I did a straight copy, the image was displayed upside down. With the above code, my web-cam shows the "expected" (not like a mirror) image on screen.

QImage in Qt does not like having its buffer redirected (bits() is functionally read-only), in OpenCV you can redirect their image buffers to write directly into the QImage buffer space, but again when there is a problem with flipping this doesn't gain much.

Oh, and about the lock, I was just avoiding the overhead - I'm using a 5 frame capture buffer and the worst result I can imagine is if things are falling behind, the image will look a little disjointed, but if things are falling behind, the images are going to be disjointed anyway, so... why make the problem worse with (a tiny bit of) additional processing?