Question

I'm a newbie in QT and C++, I'm trying to create a QTcpserver using QThreadpools so it can handle multiple clients. Multiple clients are able to connect without any issues. But I'm trying to send an image from an android phone, with a footer "IMGPNG", indicating the end of image data. Now the issue when the readyRead signal is emitted I'm tring to read all the data available data and then perform some string operation later and reconstruct the image. I'm not sure how to receive the complete image for each client and then process it accordingly.

 void VireClients::readyRead()//read ready
{

 int nsize = socket->bytesAvailable();//trying to check the available bytes

 qDebug()<< "Bytes Available" << nsize;

 while(socket->bytesAvailable() < nsize){

     QByteArray data = socket->readAll();//how to receive all the data and then process it

 }

   /*!These lines call the threadpool instance and reimplement run*/
   imageAnalysis = new VireImageAnalysis(); //creating a new instance of the QRunnable
   imageAnalysis->setAutoDelete(true);
      connect(imageAnalysis,SIGNAL(ImageAnalysisResult(int)),this,SLOT(TaskResult(int)),Qt::QueuedConnection);
   QThreadPool::globalInstance()->start(imageAnalysis);


}

Now i'm not sure how to get the data completely or save the received data in an image format. i want to know how to completely receive the image data. Please help.

Was it helpful?

Solution 2

Solved saving image issue by collecting, the string in temp variable and finally, used opencv imwrite to save the image, this solved this issue:

 while(iBytesAvailable > 0 )
     {
      if(socket->isValid())
      {
       char* pzBuff = new char[iBytesAvailable];
       int iReadBytes = socket->read(pzBuff, iBytesAvailable);
       if( iReadBytes > 0 )
       {
           result1 += iReadBytes;

            str += std::string(reinterpret_cast<char const *>(pzBuff), iReadBytes);


            if(str.size() > 0){
                search = str.find("IMGPNG");

                if(search == result1-6){

                    finalID = QString::fromStdString(str);

                    Singleton_Global *strPtr = Singleton_Global::instance();
                    strPtr->setResult(finalID);

                    /*!Process the received image here*/
                    SaveImage= new VSaveImage();
                    SaveImage->setAutoDelete(false);
                    connect(SaveImage,SIGNAL(SaveImageResult(QString)),this,SLOT(TaskResult(QString)),Qt::QueuedConnection);
                    threadPool->start(SaveImage);

                }
            }

       }

Finally did the image saving on the run method -->SaveImage, @DavidSchwartz you were a great help thanks. Thanks all for your help.

OTHER TIPS

A call to readAll() will not always read the complete image as it obviously cannot know the size of the image. It will only read all currently available bytes which might be less than your whole file, or more if the sender is really fast and you cannot catch up reading. The same way readyRead() only informs you that there are bytes available but not that a whole file has been received. It could be a single byte or hundreds of bytes.

Either you know the size of your image in the first place because it is always fixed or the sender has to tell the receiver the number of bytes he wants to sent.

Then you can either just ignore all readyRead() signals until bytesAvailable() matches your image size and call readAll() to read the whole image at once. Or you read whenever there are available bytes and fill up your buffer until the number of bytes read matches the bytes the receiver told you he will send.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top