QT failed to load Image from Buffer - c++

My work Environment : Qt 5.8 MSVC2015 64bit, QT GraphicsView, Windows 7 64 bit
I am loading image from buffer (a demon process is going send a image buffer), but it failed to create image with buffer.
QFile file("D:\\2.png");
if (!file.open(QFile::ReadOnly))
qDebug() << "Error failed to Open file";
QByteArray array = file.readAll();
array = array.toBase64();
QImage tempimage((uchar *)array.data(), 250, 250, QImage::Format_RGBX8888);
if (!tempimage.isNull()) {
///I always get this error
qDebug() << "Error!!! failed to create a image!";
}
Any idea what I am missing here ?

Why are you converting to base64?
Wait, where are you converting from PNG to an image plane?
Try bool QImage::loadFromData(const QByteArray &data, const char *format = Q_NULLPTR) to load the PNG instead of the CTor with the raw data.
If your wire format isn't PNG (and is in fact base64 encoded raw pixel data) then you want to convert FROM base64.

Thanks for all suggestion & help.
I fix my mistakes removed base64 conversion & loaded buffer using loadFromData with QByteArray reinterpret_cast:
Here is a final solution :
QFile file("D:\\2.png");
if (!file.open(QFile::ReadOnly))
qDebug() << "Error failed to Open file";
QByteArray array = file.readAll();
QImage tempimage;
//// This very important to cast in below format, QByteArray don't work as arguments.
tempimage.loadFromData(reinterpret_cast<const uchar *>(array.data()),array.size());
if (tempimage.isNull()) {
qDebug() << "Error!!! failed to create a image!";
}

Related

how to transfer QImage from QLocalServer to QLocalSocket

I have two mac apps that communicate with each other using QLocalSocket.
Able to send the received QString but not able to send the received QImage Below is my code.
SERVER SIDE CODE
QImage image(":/asset/logo_active.png");
QByteArray ba;
qDebug() << image.sizeInBytes() <<image.size();
ba.append((char *)image.bits(),image.sizeInBytes());
qDebug() <<ba.size(); //262144
this->mSocket->write(ba);
if(!this->mSocket->waitForBytesWritten(-1))
{
qDebug() << "writen Bytes error " << this->mSocket->errorString();
}
this->mSocket->flush();
CLIENT SIDE CODE
connect(mLocalSocket,&QLocalSocket::readyRead, [&]() {
QByteArray ba;
ba = mLocalSocket->readAll();
qDebug() << "size is" << ba.size(); // size is 0
QImage image((uchar *)ba.data(),1024,768,QImage::Format_RGB32);
ui->labelStream->setPixmap(QPixmap::fromImage(img));
});
at sender 262144 is the byte-array size
but at the receiver, byte-array size is 0
Do let me know if I am missing anything.
Thanks In Advance
Finally I got the solutions I used QDataStream below is the code example.
SERVER SIDE CODE:
QDataStream T(mSocket);
T.setVersion(QDataStream::Qt_5_7);
QByteArray ba;
ba.append((char *)img.bits(),img.sizeInBytes());
T << ba;
mSocket->flush();
CLIENT SIDE CODE
QByteArray jsonData;
QDataStream socketStream(mLocalSocket);
socketStream.setVersion(QDataStream::Qt_5_7);
for (;;) {
socketStream.startTransaction();
socketStream >> jsonData;
if (socketStream.commitTransaction()) {
QImage image((uchar *)jsonData.data(),640,480,QImage::Format_RGB888);
ui->labelStream->setPixmap(QPixmap::fromImage(image));
}else {
// the read failed, the socket goes automatically back to the state it was in before the transaction started
// we just exit the loop and wait for more data to become available
break;
}
}
Thanks, Everyone for your support also Stackoverflow.

Receiving jpeg through socket and yet unable to display on Qt

I trying to send and receive jpeg images (image size around: 1kb) from my client socket. I have successfully send and receive the image data by checking the size of the data. However when I tried to past the image data to QByteArray and display on QImage, nothing was shown. The code below is a snippet of the receiving and displaying jpeg image.
Server.cpp
memcpy(&Rbuffer, ptr, msgCtl.iMsgLen - 8);
ptr += msgCtl.iMsgLen - 8;
cout << "Size of the image data recieve from the send buffer is " << sizeof(Rbuffer) << endl;
QByteArray ba = QByteArray::fromRawData(Rbuffer, sizeof(Rbuffer));
QBuffer qbuff(&ba);
qbuff.open(QIODevice::ReadOnly);
//QImageReader qimg ("C:\\test.jpg");
QImageReader qimg (&qbuff,"JPG");
qimg.setDecideFormatFromContent(true);
qimg.setDevice(&qbuff);
QImage img = qimg.read();
if (!img.isNull()){
cout << "no problem" << endl;
}
imageView->setPixmap(QPixmap::fromImage(img));
Hope someone could guide me on this. Thank you
On Windows, you have to copy the imageformats directory to your build directory.
eg.
C:\Qt\5.7\msvc2015_64\plugins\imageformats to my_build_dir\imageformats
Try this code:
QPixmap scaledPixmap = QPixmap::fromImage(image).scaled(
QSize(imageWidth, imageHeight),
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
imageView->setScaledContents(false);
imageView->setPixmap(scaledPixmap);

How to read my application screen pixel data with Qt

I am trying to read my application screen pixel data in my Qt Qml application.
The first approach was grabToImage(), which is fast in my PC. But the same is taking seconds to grab image in my embedded device.
So I tried to read /dev/fb0, using QFile::readAll,
QFile file("/dev/fb0");
QFile dataFile("/home/icu/WorkSpace/Samples/FBRead/Exe/data.bin");
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << Q_FUNC_INFO << file.errorString();
}
if(!dataFile.open(QIODevice::WriteOnly))
{
qDebug() << Q_FUNC_INFO << dataFile.errorString();
}
QTextStream in(&file);
QString data;
qDebug() << Q_FUNC_INFO << "start read";
// while(!in.atEnd())
// {
qDebug() << Q_FUNC_INFO << "read";
data = in.readAll();
// qDebug() << Q_FUNC_INFO << data;
// }
QByteArray dataBytes;
dataBytes.append(data);
dataFile.write(dataBytes);
file.close();
dataFile.close();
I tried to open the file with some tool which shows image reading from raw file. But it did not show any data. When I open the file data is like 01 01 01 00 01 01 01 00 ...
Is there any alternate way to read my screen pixel data fast? Thanks
I'm not sure if using a QTextStream and converting data to QString and then back to QByteArray is the best way to do it. As explained in Qt's documentation constructing a QString from QByteArray forces a conversion to UTF-8 and also stops copying at the first null character, so you are modifying your pixel data and not getting it completely. Try copying data directly between files instead:
bool grabScreenToFile(const QString& outPath) {
QFile inFile("/dev/fb0");
QFile outFile(outPath);
// ...
outFile.write(inFile.readAll());
return true;
}
To check if this is copying the actual content of the file and you have no problem with it (truncation, conversions, ...), compare with the file obtained using cat /dev/fb0 > grab.raw (note that it is not a JPEG or PNG image but a raw buffer).
/dev/fb0
This link contains a long explanation about grabbing the framebuffer from the /dev/fb0 device. Basically, it points out that you must pay attention to the depth of the buffer, since pixels may be packed in different ways.
On the other hand, have you tried any other of the grabbing methods provided by Qt, such as QScreen::grabWindow? Maybe its performance is better that the QML's QQuickItem::grabToImage (which is the one I guess you are using). Indeed, the documentation states:
This function will render the item to an offscreen surface and copy that surface from the GPU's memory into the CPU's memory, which can be quite costly.
Following code is a modification of the screenshot example.
auto screen = QGuiApplication::primaryScreen();
if (const QWindow *window = windowHandle()) {
screen = window->screen();
}
if (screen) {
const auto pixmap = screen->grabWindow(yourWidget->winId());
// ...
}

Convert byte array to picture

Hello I try to convert a byte array to an Image but each time i get a null image, somebody could help me please ?
QImage image("p.jpg");
qDebug()<<image;
QImage image2;
QByteArray paquet2;
QDataStream out2(&paquet2, QIODevice::WriteOnly);
out2 << image;
qDebug()<<image2.fromData(paquet2,"jpg");
qDebug 1 result: QImage(Qsize(500,500))
qDebug 2 result: QImage(Qsize(0,0))
fromData() is a static method.
Try image2.loadFromData(paquet2) or QImage::fromData(paquet2) instead.
I noticed something very strange, this code works as expected:
QImage img("...");
QByteArray data;
QBuffer buff(&data);
QDataStream out(&buff);
out << img;
qDebug() << QImage::fromData(data);
But it gives a warning about the IODevice not being open.
If I manually buff.open(), fromData() produces a null image again.
Without explicitly opening, the openMode() is automatically set to Unbuffered | WriteOnly and it works, if I open() it explicitly to Unbuffered | WriteOnly it doesn't work. Go figure...

QDataStream unable to serialize data

I am trying to follow the tutorial here and serialize Qt objects. Here is my code:
QFile file("/Users/kaustav/Desktop/boo.dat");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Cannot open file for writing: "
<< qPrintable(file.errorString()) << endl; //no error message gets printed
return 0;
}
QDataStream out(&file); // we will serialize the data into the file
out.setVersion(QDataStream::Qt_5_3); //adding this makes no difference
out << QString("the answer is"); // serialize a string
out << (qint32)42;
When I run this program, the file gets created in my desktop all right, but its size is 0 kB, it is blank. Naturally, when I then try this:
QFile file("/Users/kaustav/Desktop/boo.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file); // read the data serialized from the file
in.setVersion(QDataStream::Qt_5_3);
QString str;
qint32 w;
in >> str >> w;
I get a blank string in str. What am I doing wrong? If of any help, I am using Qt Creator 3.1.1 based on Qt 5.2.1.
Check if there are any errors returned when calling open and ensure you close the file with file.close() when you're finished with it.
As you're using Qt 5, you should really use QSaveFile instead, when saving the data.