Convert jpeg image to thumbnail image in Qt - qt

A QImage needs to be finally shown as a thumbnail image in a QLabel. In between it's serialized in QByteArray and sent over the network. So, can we convert the QImage to QByteArray for thumbnail? Basically I want to avoid the QImage::scale() method as it's quite CPU consuming.
Like QImage converted to a QByteArray which will hold data for thumbnail images.

On this case you cannot avoid QImage::scale. Why do you want?
This is the answer to your question how to save QImage to QByteArray.
QFile file(imagePath);
if (file.open(QIODevice::ReadOnly)) {
QByteArray bytes;
QImage img;
img = img.fromData(file.readAll());
img = img.scaled(200, 100, Qt::IgnoreAspectRatio, Qt::FastTransformation);
SetLabelImage(img);
QBuffer buffer(&bytes);
img.save(&buffer, "PNG");
}

Related

How to copy the one QImage into another QImage?

How to copy one QImage into another QImage?
I do not want to change the size of image
QImage src=function_name();
QImage dst;
You can use the QImage::copy() function. For example:
QImage src = function_name();
QImage dst = src.copy();

Display image from raw bitmap file to bmp file

I am trying to create a QT application which will display a image (bmp) from a raw bitmap file. The raw bitmap file is of .panel file format. Its in RGB565 format.
How do we use/convert the raw bitmap (img.panel) into a bmp file, so I can use it Qimage.
QFile file("/usr/bitmap.bmp");
if (!file.open(QFile::ReadOnly))
return 0;
QByteArray array = file.readAll();
QImage image((const uchar*)array.data(), h_bitmap, v_bitmap, QImage::Format_RGB16);
image.save("/usr/test_qimg_16.bmp","BMP");
image = image.convertToFormat(QImage::Format_RGB16);
image.load("/usr/test_qimg_16.bmp");
QPixmap pixmap;
This is the image I get after this operation.
http://tinypic.com/r/kb4pd4/8
But I am expecting something like this :
http://tinypic.com/r/dptpq1/8
Thank you.
Any help is appreciated.

Optimizing QPainter drawing & Converting QVideoFrame straight to QPixMap

Some background info about my issue. My goal is to optimize drawing of images coming from webcam, the images come as QVideoFrame and are currently loaded in to QImage and drawn from there. This solution works fine, but drawing QImage is very slow on X11. Drawing one image takes about 20ms which doesn't sound like much but when you do this for every frame this cut's the framerate of the camerafeed to half.
I did some research and testing, drawing QPixMaps in X11 can be done about 10 times faster than drawing QImages.
This is how the drawing process is done currently
if(mVFcurrentFrame.map(QAbstractVideoBuffer::ReadOnly))
{
QImage image(mVFcurrentFrame.bits(), mVFcurrentFrame.width(), mVFcurrentFrame.height(), mVFcurrentFrame.bytesPerLine(), imageFormat);
painter->drawImage(0,0,image); //Takes about 20ms
mVFcurrentFrame.unmap();
}
What i have tried so far:
Converting the QImage to QPixMap, this works but the conversion is as slow as painting the Qimage
Loading the QVideoFrame straight to QPixMap with QPixMap::loadFromData(), can't make it work.
So my question is, can i convert QVideoFrame straight to QPixMap and draw it instead of using QImage and how would you do the QVideoFrame to QPixmap conversion without using QImage in between?
I have tried using QPixMap::loadFromData() method to load the video frame but so far i have been unable to make it work.
If this isn't possible could i thread the QImage to QPixMap conversion or optimize the drawing in some other way?
This is my problem too.
camera frames are shown very slowly in QLabel.
my code is here:
QCamera *camera = new QCamera(this);
camera->setCaptureMode(QCamera::CaptureViewfinder);
QVideoProbe *videoProbe = new QVideoProbe(this);
bool ret = videoProbe->setSource(camera);
if (ret) {
connect(videoProbe, SIGNAL(videoFrameProbed(const QVideoFrame &)),
this, SLOT(present(const QVideoFrame &)));
}
camera->start();
...
...
bool MainWindow::present(const QVideoFrame &frame)
{
QVideoFrame cloneFrame(frame);
if(cloneFrame.map(QAbstractVideoBuffer::ReadOnly))
{
QImage img(
cloneFrame.size(), QImage::Format_ARGB32);
qt_convert_NV21_to_ARGB32(cloneFrame.bits(),
(quint32 *)img.bits(),
cloneFrame.width(),
cloneFrame.height());
label->setPixmap(QPixmap::fromImage(img));
cloneFrame.unmap();
}
return true;
}

load image from char buffer

I need to construct an image with unsigned char data I receive from a compressed/decompressed image. For this, I just wrote a simple program to test buffer loading from image and vice versa. As I run the code, I cannot setpixmap the image to the background.
void MainWindow::LoadImage()
{
//======== Load buffer from image
unsigned char buffer[_width*_height*COLOR_COMPONENTS]; //1024 * 768 * 3
QImage image;
image.load("://image.jpg", "JPEG");
memcpy(buffer, image.bits(), _width*_height*COLOR_COMPONENTS);
//========= Load image from buffer
QImage img;
img.loadFromData((const char*)buffer);
QPixmap px = QPixmap::fromImage(img);
ui->label->setPixmap(px);
}
UPDATED:
I changed the code to this, however, I get segmentation fault with memcpy.
unsigned char buffer[400*300*3];
QImage image(_width, _height, QImage::Format_RGB32);
image.load("://image.jpg", "JPEG");
memcpy(buffer, image.bits(), 400*300*3);
QImage img(400, 300, QImage::Format_RGB32);
img.loadFromData((const uchar*)buffer, sizeof(buffer)/sizeof(char), "JPG");
QPixmap px = QPixmap::fromImage(img);
ui->label->setPixmap(px);
loadFromData requires the data to be in a certain format (PNG, JPG...), the plain array is not a valid one
however doing
QImage img(buffer,_width, _height, QImage::Format_RGB888);
will return a image of the correct size and format but will only be valid for as long as buffer is alive

set image raw data buffer to QMediaPlayer

I want to get a screen shot of the widget application and then set its raw data buffer to QMeidaPlayer with setMedia(). What I have done so far is to receive the image, SAVE it, and then read from it. However, I would like to ask you how to read raw data directly without saving it into media player:
QPixmap originalPixmap = QPixmap::grabWidget(this);
QImage *image = new QImage(originalPixmap.toImage());
QByteArray ba;
QBuffer buffer(&ba);
buffer.setBuffer(&ba);
buffer.open(QIODevice::WriteOnly);
image->save(&buffer); // writes image into ba in PNG format
image->save(image Path);
mediaPlayer.setMedia(QUrl::fromLocalFile(image path)); //I want this to read from raw data
mediaPlayer.play();
I want this to take the minimum CPU usage. However, saving and reading from file consumes lots of CPU,47%.
Cheers,
Update: I tested the program with this code snippet as well. But it does not draw the buffer contents on video widget.
QBuffer *buffer = new QBuffer(image_ba);
QMediaContent media;
mediaPlayer.setMedia(media, buffer);
mediaPlayer.play();
Any ideas how I can resolve this to input image raw data to video widget?
here's how you can do it:
QPixmap originalPixmap = QPixmap::grabWidget(this);
QBuffer *buffer = new QBuffer(); // make sure that your buffer has the same life span as your media player, or otherwise the media player would try to read data from non-existing buffer. (the setMedia() and play() methods are non-blocking)
buffer.open(QIODevice::ReadWrite);
originalPixmap.save(buffer, "PNG"); // can be any other format, not just PNG
mediaPlayer.setMedia(QUrl(), buffer);
mediaPlayer.play();

Resources