1

I'm working on an application that takes shows a live feed from an 18 Megapixel IDS uEye Camera.

The three options that I have for displaying the image are 1) Using a Direct3D method from the API to draw to a QWidget using (HWND)QWidget->winId(). 2) Using a Bitmap Rendering method from the API to draw to a QWidget using (HWND)QWidget->winId(). 3) Creating a QImage from the raw sensor data (a char* buffer) and updating the GUI with the QImage.

Because I would like to use the features of the QImage class for my application, I am currently pursuing that last option.

I am able to successfully convert the image from the camera with the following code:

// Collect the image.
int nRet = is_GetImageMem(m_hCam, &m_pcLongImageMemory);
if( nRet != IS_SUCCESS)
{
    // handle error
}

//Put in unique_ptr<> to QImage
img.reset((new QImage((uchar*)m_pcImageMemory, m_nSizeX, m_nSizeY, QImage::Format::Format_RGB888)));
ui.widget->setImage(img.get());

This does fine in terms of generating the image that I will use. I then want to paint the image to a QWidget. For this, following advice from this thread, I have been able to successfully take these large, 18 MP images and update the GUI with them.

So, my problem arises with the following method:

void ImageFrame::paintEvent(QPaintEvent*) {
  if (!m_image) { return; }

  QPainter painter(this);
  painter.drawImage(this->rect(), *m_image, m_image->rect());
}   

My problem is with the adjustments made by the QPainter::paintImage() method being used. It seems that most of the overloads for ::paintImage() will automatically stretch the image to fit the bounding rectangle. In my case, I would prefer to maintain the 4:3 aspect ratio of my image at all times to avoid any distortion for the user. In this case, I have not found a QRect() configuration that will allow me to update the GUI with this image without stretching.

It seems like my options are either to rescale the image to the size of the widget in the GUI (which seems very, very expensive with an image this size) or else to find a way to fix the size of this QWidget subclass so that it always scales into the maximum 4:3 ratio configuration it can within its surrounding layout...

Any help or insight that someone might be able to provide is appreciated.

Community
  • 1
  • 1
Kettamon
  • 97
  • 8
  • It's on you to provide a target rectangle with correct aspect ratio. You don't need nor want to paint the entire widget. Do a horizontal or vertical letterbox as appropriate. – Kuba hasn't forgotten Monica Jul 01 '16 at 15:36
  • If you want to constrain your widget to a 4:3 aspect ratio you can do it via the various `heightForWidth` functions (in QWidget / QLayout / QSizePolicy). Otherwise just calculate the right rectangle to scale your image into while keeping the aspect ratio. – peppe Jul 01 '16 at 15:37
  • @KubaOber By this you mean to adjust the source rectangle argument into a letter-boxed shape relative to the widgets.rect()? I think I see what you mean there. I'll give that a shot. – Kettamon Jul 01 '16 at 15:40
  • @Ketta The source rectangle is, I presume, the entire image. The target rectangle should be a scaled version of the source, so that it maintains the 4:3 ratio. – Kuba hasn't forgotten Monica Jul 01 '16 at 15:42
  • @KubaOber Ok, I got it working with your suggestion. Thanks so much for the tip. I found that making a copy of the Widget's QRect and then adjusting the left and right bounds works perfectly. – Kettamon Jul 01 '16 at 16:16
  • Btw, I feel that drawing a 18megapixel image this way is going to put your CPU under tremendous load. Ideally for this kind of things you want to use proper, accelerated video show. If the camera supports DirectShow, you could use QtMultimedia, for instance. Otherwise: if the camera drivers document that requesting RGB is going to perform frame decompression and colorspace conversion on the CPU, you could at least request YUV and use some other technology (OpenGL, DirectShow, XVideo, ...) perform the colorspace conversion at a way, way cheaper cost. – peppe Jul 01 '16 at 18:38
  • That's a good point @peppe. I'll be sure to look into those as other options when I get back at it. I can only get about 5 FPS out of the camera at this resolution anyway, but it is expensive and I was considering moving things along with a buffer in a separate thread. My main concern has been trying to find a way to implement this in such a way that I can use mouse events and such to draw and select regions of the image. If I'm still able to obtain that functionality with QtMultimedia or something similar then I'll try to make the switch. Thanks for your thoughts. – Kettamon Jul 01 '16 at 22:15

0 Answers0