Send image inside Json through QTcpSocket
-
@Christian-Ehrlicher
Ok, I removed theqjo.insert("photo", obj["photo"].toString());line but it still won't work.By the way, I noticed something in my client. This is the part where it receives data from the server:
QByteArray dataReceived; QDataStream ds(sock); while(sock->bytesAvailable()){ ds.startTransaction(); ds >> dataReceived; } ds.commitTransaction(); while(sock->bytesAvailable()){ // Start the transaction ds.startTransaction(); // Read data ds >> dataReceived; // Error checking if ((!ds.commitTransaction()) && (ds.status()!=QDataStream::Ok)){ sock->flush(); qDebug() << "Error!"; return; } } QString string = (QString)dataReceived; QJsonDocument doc = QJsonDocument::fromJson(string.toUtf8()); QJsonObject obj = doc.object(); ... QJsonValue photo = obj.take("photo"); qDebug() << photo.toString();Then the output, in all the examples, is:
Error! Error! Error! Error! Error! Error!and it reaches the part where it reads the photo data. There is something wrong when the client receives data, maybe?
@Tamfub
Dunno, let's start withwhile(sock->bytesAvailable()){ ds.startTransaction(); ds >> dataReceived; } ds.commitTransaction();Why would you (at least potentially) start multiple transactions and only commit once at the end?
Next, I don't understand your whole sequential
bytesAvailable()loops. Why two loops? Are you sure your transactions/tests tally against what is being sent in the same fashion?Practice code just sending string
"hello", perhaps with transactions commented out, while you verify the protocol is correct? Then move to the base64 stuff. And debug out the first & last few characters sent & received to verify they correspond before you look at decoding. You want to discover where your issue is little by little. -
@Tamfub
Dunno, let's start withwhile(sock->bytesAvailable()){ ds.startTransaction(); ds >> dataReceived; } ds.commitTransaction();Why would you (at least potentially) start multiple transactions and only commit once at the end?
Next, I don't understand your whole sequential
bytesAvailable()loops. Why two loops? Are you sure your transactions/tests tally against what is being sent in the same fashion?Practice code just sending string
"hello", perhaps with transactions commented out, while you verify the protocol is correct? Then move to the base64 stuff. And debug out the first & last few characters sent & received to verify they correspond before you look at decoding. You want to discover where your issue is little by little. -
Hi,
@Tamfub said in Send image inside Json through QTcpSocket:
QString string = (QString)dataReceived;
dataReceived is a QByteArray, that cast is completely wrong.
-
@Christian-Ehrlicher @JonB
I've given a look to the fortune client and server examples and tried to toy with data.In
server.cpp, I replacedout << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];with
QString str; for(int i=0; i<1000000; i++) str.append("a"); out << str;void Client::readFortune() became:
void Client::readFortune() { in.startTransaction(); QString data; in >> data; qDebug() << "data: " << data; if (!in.commitTransaction()) return; qDebug() << "data (end): "; qDebug() << data; // if (nextFortune == currentFortune) { // QTimer::singleShot(0, this, &Client::requestNewFortune); // return; // } // currentFortune = nextFortune; // //statusLabel->setText(currentFortune); // qDebug() << "current: " << currentFortune; // getFortuneButton->setEnabled(true); qDebug() << "finished"; }The output in the client is:
next: "" next (end): finishedI guess
qDebug()does not print large data? -
@Christian-Ehrlicher @JonB
I've given a look to the fortune client and server examples and tried to toy with data.In
server.cpp, I replacedout << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];with
QString str; for(int i=0; i<1000000; i++) str.append("a"); out << str;void Client::readFortune() became:
void Client::readFortune() { in.startTransaction(); QString data; in >> data; qDebug() << "data: " << data; if (!in.commitTransaction()) return; qDebug() << "data (end): "; qDebug() << data; // if (nextFortune == currentFortune) { // QTimer::singleShot(0, this, &Client::requestNewFortune); // return; // } // currentFortune = nextFortune; // //statusLabel->setText(currentFortune); // qDebug() << "current: " << currentFortune; // getFortuneButton->setEnabled(true); qDebug() << "finished"; }The output in the client is:
next: "" next (end): finishedI guess
qDebug()does not print large data? -
Hi,
@Tamfub said in Send image inside Json through QTcpSocket:
QString string = (QString)dataReceived;
dataReceived is a QByteArray, that cast is completely wrong.
-
@Tamfub said in Send image inside Json through QTcpSocket:
I guess qDebug() does not print large data?
Do not rely on
qDebug()output visibility. I think it says somewhereqDebug(qPrintable(qString)); or printQString::length().@JonB
Ok, I put some printing of the sizes, and found out that receivedData.size() = 2 x sentData.size().Server
ds << QString::fromLatin1(ba.toBase64()); qDebug() << "size: " << QString::fromLatin1(ba.toBase64()).size(); // 75684Client
ds.startTransaction(); QByteArray data; ds >> data; if (!ds.commitTransaction()) return; qDebug() << "data(size): " << risp.size(); // 151368How is this possible? If I try with
QByteArray str; for(int i=0; i<1000000; i++) str.append("a"); ds << str; qDebug() << "size: " << str.size(); // 1000000instead, the two sizes match!
-
@JonB
Ok, I put some printing of the sizes, and found out that receivedData.size() = 2 x sentData.size().Server
ds << QString::fromLatin1(ba.toBase64()); qDebug() << "size: " << QString::fromLatin1(ba.toBase64()).size(); // 75684Client
ds.startTransaction(); QByteArray data; ds >> data; if (!ds.commitTransaction()) return; qDebug() << "data(size): " << risp.size(); // 151368How is this possible? If I try with
QByteArray str; for(int i=0; i<1000000; i++) str.append("a"); ds << str; qDebug() << "size: " << str.size(); // 1000000instead, the two sizes match!
@Tamfub said in Send image inside Json through QTcpSocket:
qDebug() << "size: " << QString::fromLatin1(ba.toBase64()).size(); // 75684qDebug() << "data(size): " << risp.size(); // 151368What arithmetic formula do you notice connects the two numbers in your comments? :)
-
@Tamfub said in Send image inside Json through QTcpSocket:
qDebug() << "size: " << QString::fromLatin1(ba.toBase64()).size(); // 75684qDebug() << "data(size): " << risp.size(); // 151368What arithmetic formula do you notice connects the two numbers in your comments? :)
-
@JonB I already noticed the receivedData in double the sentData, I wrote it before. But I can't understand why.
-
@JonB I already noticed the receivedData in double the sentData, I wrote it before. But I can't understand why.
-
I managed to fix the (un)packing during the sending/receiving part. Now I miss the final step: create a Pixmap from the received data and show it. To sum up:
Server
QImage imageObject; imageObject.load(Path/to/image); QPixmap image = QPixmap::fromImage(imageObject); QByteArray ba; // Construct a QByteArray object QBuffer buffer(&ba); // Construct a QBuffer object using the QbyteArray image.save(&buffer, "JPG"); // Save the QImage data into the QBuffer qjo.insert("request_type", PHOTO_REQUEST); qjo.insert("photo", QString::fromLatin1(ba.toBase64())); qDebug() << "Size of QString::fromLatin1(ba.toBase64())): " << QString::fromLatin1(ba.toBase64()).size(); // 470184 QJsonDocument doc(qjo); QString strJson(doc.toJson(QJsonDocument::Compact)); info.append(strJson); ds << info;Client
ds.startTransaction(); QByteArray risp; ds >> risp; qDebug() << "risp: " << risp; if (!ds.commitTransaction()) return; ... QJsonValue photo = obj.take("photo"); QByteArray ba = photo.toString().toLatin1(); qDebug() << "photo data size (latin): " << photo.toString().toLatin1().size(); // 470184 //qDebug() << "photo size (utf8): " << photo.toString().toUtf8().size(); QPixmap pm; ??? // Missing part ui->myLabel->setPixmap(pm);ui->myLabelhas anotherPixmapset at the moment. In the???part, I tried:if(!pm.loadFromData(ba, "JPG")){ qDebug() << "Error: data could not be loaded."; return; }and it always ended up printing the error message.
Then, I read this and tried
const uchar * const data = reinterpret_cast<const uchar *>(ba.constData()); qDebug() << "uchar size: " << data; QPixmap pixmap = QPixmap::fromImage( QImage( data, ui->myLabel->width(), ui->myLabel->height(), QImage::Format_RGB888 ) );The previous
Pixmapofui->myLabelis removed, but now there is a white one. Any ideas? -
I managed to fix the (un)packing during the sending/receiving part. Now I miss the final step: create a Pixmap from the received data and show it. To sum up:
Server
QImage imageObject; imageObject.load(Path/to/image); QPixmap image = QPixmap::fromImage(imageObject); QByteArray ba; // Construct a QByteArray object QBuffer buffer(&ba); // Construct a QBuffer object using the QbyteArray image.save(&buffer, "JPG"); // Save the QImage data into the QBuffer qjo.insert("request_type", PHOTO_REQUEST); qjo.insert("photo", QString::fromLatin1(ba.toBase64())); qDebug() << "Size of QString::fromLatin1(ba.toBase64())): " << QString::fromLatin1(ba.toBase64()).size(); // 470184 QJsonDocument doc(qjo); QString strJson(doc.toJson(QJsonDocument::Compact)); info.append(strJson); ds << info;Client
ds.startTransaction(); QByteArray risp; ds >> risp; qDebug() << "risp: " << risp; if (!ds.commitTransaction()) return; ... QJsonValue photo = obj.take("photo"); QByteArray ba = photo.toString().toLatin1(); qDebug() << "photo data size (latin): " << photo.toString().toLatin1().size(); // 470184 //qDebug() << "photo size (utf8): " << photo.toString().toUtf8().size(); QPixmap pm; ??? // Missing part ui->myLabel->setPixmap(pm);ui->myLabelhas anotherPixmapset at the moment. In the???part, I tried:if(!pm.loadFromData(ba, "JPG")){ qDebug() << "Error: data could not be loaded."; return; }and it always ended up printing the error message.
Then, I read this and tried
const uchar * const data = reinterpret_cast<const uchar *>(ba.constData()); qDebug() << "uchar size: " << data; QPixmap pixmap = QPixmap::fromImage( QImage( data, ui->myLabel->width(), ui->myLabel->height(), QImage::Format_RGB888 ) );The previous
Pixmapofui->myLabelis removed, but now there is a white one. Any ideas?@Tamfub said in Send image inside Json through QTcpSocket:
ow I miss the final step: create a Pixmap from the received data and show it. To sum up:
Have you take a look at QPixmap documentation? I think you will quickly find
QPixmap::loadFromData()... -
@Tamfub said in Send image inside Json through QTcpSocket:
ow I miss the final step: create a Pixmap from the received data and show it. To sum up:
Have you take a look at QPixmap documentation? I think you will quickly find
QPixmap::loadFromData()...@KroMignon
Hi.
I eventually managed to show the image. I was missing:ba = ba.fromBase64();before
pm.loadFromData(...), and now it works. Thanks!