Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Send image inside Json through QTcpSocket
Qt 6.11 is out! See what's new in the release blog

Send image inside Json through QTcpSocket

Scheduled Pinned Locked Moved Solved General and Desktop
28 Posts 6 Posters 18.5k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ JonB

    @Tamfub
    Dunno, let's start with

    while(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.

    T Offline
    T Offline
    Tamfub
    wrote on last edited by
    #15

    @Christian-Ehrlicher @JonB
    Ok, I guess I'll have to revise my protocol, then I'll return to the other problem later :)

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #16

      Hi,

      @Tamfub said in Send image inside Json through QTcpSocket:

      QString string = (QString)dataReceived;

      dataReceived is a QByteArray, that cast is completely wrong.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      T 1 Reply Last reply
      1
      • T Offline
        T Offline
        Tamfub
        wrote on last edited by
        #17

        @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 replaced

        out << 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): 
        finished
        

        I guess qDebug() does not print large data?

        JonBJ 1 Reply Last reply
        0
        • T Tamfub

          @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 replaced

          out << 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): 
          finished
          

          I guess qDebug() does not print large data?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #18

          @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 somewhere qDebug(qPrintable(qString)); or print QString::length().

          T 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            @Tamfub said in Send image inside Json through QTcpSocket:

            QString string = (QString)dataReceived;

            dataReceived is a QByteArray, that cast is completely wrong.

            T Offline
            T Offline
            Tamfub
            wrote on last edited by
            #19

            @SGaist
            Hi.
            Ok, I guess I should use something like QString::fromLatin1(array), right?

            1 Reply Last reply
            0
            • JonBJ JonB

              @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 somewhere qDebug(qPrintable(qString)); or print QString::length().

              T Offline
              T Offline
              Tamfub
              wrote on last edited by Tamfub
              #20

              @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(); // 75684
              

              Client

              ds.startTransaction();
              QByteArray data;
              ds >> data;
              
              if (!ds.commitTransaction())
                      return;
              
              qDebug() << "data(size): " << risp.size();  // 151368
              

              How 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();  // 1000000
              

              instead, the two sizes match!

              JonBJ 1 Reply Last reply
              0
              • T Tamfub

                @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(); // 75684
                

                Client

                ds.startTransaction();
                QByteArray data;
                ds >> data;
                
                if (!ds.commitTransaction())
                        return;
                
                qDebug() << "data(size): " << risp.size();  // 151368
                

                How 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();  // 1000000
                

                instead, the two sizes match!

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #21

                @Tamfub said in Send image inside Json through QTcpSocket:

                qDebug() << "size: " << QString::fromLatin1(ba.toBase64()).size(); // 75684

                qDebug() << "data(size): " << risp.size(); // 151368

                What arithmetic formula do you notice connects the two numbers in your comments? :)

                T 1 Reply Last reply
                0
                • JonBJ JonB

                  @Tamfub said in Send image inside Json through QTcpSocket:

                  qDebug() << "size: " << QString::fromLatin1(ba.toBase64()).size(); // 75684

                  qDebug() << "data(size): " << risp.size(); // 151368

                  What arithmetic formula do you notice connects the two numbers in your comments? :)

                  T Offline
                  T Offline
                  Tamfub
                  wrote on last edited by Tamfub
                  #22

                  @JonB I already noticed the receivedData in double the sentData, I wrote it before. But I can't understand why.

                  JonBJ mrjjM 2 Replies Last reply
                  0
                  • T Tamfub

                    @JonB I already noticed the receivedData in double the sentData, I wrote it before. But I can't understand why.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #23

                    @Tamfub
                    Because one is a QByteArray and one is a QString? You can't send one type, decode it as a different type, and expect them to be the same.

                    1 Reply Last reply
                    1
                    • T Tamfub

                      @JonB I already noticed the receivedData in double the sentData, I wrote it before. But I can't understand why.

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #24

                      @Tamfub
                      Hi
                      QString is 16 bit. QByteArray is 8bit

                      T 1 Reply Last reply
                      0
                      • mrjjM mrjj

                        @Tamfub
                        Hi
                        QString is 16 bit. QByteArray is 8bit

                        T Offline
                        T Offline
                        Tamfub
                        wrote on last edited by
                        #25

                        @JonB @mrjj
                        you're damn right, I didn't notice that. My bad :)
                        Thank you both! Now I will try to pack/unpack correctly.

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          Tamfub
                          wrote on last edited by
                          #26

                          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->myLabel has another Pixmap set 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 Pixmap of ui->myLabel is removed, but now there is a white one. Any ideas?

                          KroMignonK 1 Reply Last reply
                          0
                          • T Tamfub

                            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->myLabel has another Pixmap set 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 Pixmap of ui->myLabel is removed, but now there is a white one. Any ideas?

                            KroMignonK Offline
                            KroMignonK Offline
                            KroMignon
                            wrote on last edited by KroMignon
                            #27

                            @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()...

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            T 1 Reply Last reply
                            1
                            • KroMignonK KroMignon

                              @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()...

                              T Offline
                              T Offline
                              Tamfub
                              wrote on last edited by Tamfub
                              #28

                              @KroMignon
                              Hi.
                              I eventually managed to show the image. I was missing:

                              ba = ba.fromBase64();
                              

                              before pm.loadFromData(...), and now it works. Thanks!

                              1 Reply Last reply
                              1

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved