I'm new to Qt and I have been trying to develop a simple video streaming application.
While developing my app, I've been facing a problem I thought could be ignored at first, but that's not the case. In fact, this problem is slowing down my whole application and is making it not working.
Here's my problem: When I'm trying to display many images I have 2 choices:
Using the QImage constructor QImage(uchar *data, int width, int height, QImage::Format format) to construct the image and display it. It's working as intended but is VERY, VERY slow
Or load the data of the images with QImage::loadFromData(uchar *, int len), which is simply not working.
Here's my working code:
void MainWindow::startCapturing()
{
timer->start();
// on press of a button, the timer will call repeatedly the generateImage() function
}
void MainWindow::generateImage()
{
det->GetImage(&image); // fulfill my image with data
myImage=QImage((uchar*)image.GetValuePointer(),image.GetSize().height,image.GetSize().width,
QImage::Format_Grayscale16);
// here GetValuePointer returns a void *, that's why we had to cast it.
ui->img_label->setPixmap(QPixmap::fromImage(myImage));
}
Here's my not working code
void MainWindow::startCapturing2()
{
myImage=QImage((uchar*)image.GetValuePointer(),image.GetSize().height,image.GetSize().width,
QImage::Format_Grayscale16);
ui->img_label->setPixmap(QPixmap::fromImage(myImage));
timer->start();
// on press of a button, the timer will call repeatedly the generateImage() function
}
void MainWindow::generateImage2()
{
det->GetImage(&image);
myImage.loadFromData((uchar *)image.GetValuePointer(), image.GetSizeInBytes());
// same cast of GetValuePointer as above
ui->img_label->setPixmap(QPixmap::fromImage(myImage));
}
INFORMATIONS ABOUT THE CODE:
det->GetImage(&image) fulfill my Image object named image here.
Image is my own type because I'm working with specific cameras and had to do so, it's more on the hardware side, don't bother with that.
image.GetValuePointer() returns the data of the image as a void * to be cast in anything you want.
don't bother with timer() and startCapturing() as well, it's working, that's not the point of the topic.
in StartCapturing2, I'm trying to create the QImage, and set the pixmap so that if I update myImage with loadFromData, it will change the image displayed.
I've been trying many things, like a lot of them, using a QByteArray for example but it's either not working or simply not what I want.
If you have any question, please ask them I will try to answer as fast and best as I can! Thanks!
You haven't provided any value for the format
parameter for loadFromData()
(default value is nullptr
) so most likely QImage
tries to find a image header, doesn't find any and gives up, not being able to handle the following data.
The loader attempts to read the image using the specified format, e.g., PNG or JPG. If format is not specified (which is the default), the loader probes the file for a header to guess the file format.
On a side note, your second option might be even slower than the first because it copies the data while the first one uses the existing data from image. See constructor documentation (emphasis mine):
QImage::QImage(const uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
Constructs an image [...] that uses an existing read-only memory buffer, data.