PDA

View Full Version : QImage sent through QDataStream



dfink
1st December 2009, 11:48
Hi,

I'm trying to send images over a network connection the easiest way possible. Its not a Video stream and its only local network, so the bandwidth usage is not that important.

I've tried two approaches till now:

First using the overloaded << operator "QDataStream << QImage"

Client Side:


// QImage image is already instantiated
_socket->connectToHost("127.0.0.1", 11111, QIODevice::ReadWrite);
QDataStream stream(_socket);
stream << image;
_socket->waitForBytesWritten(-1);


Server Side:


QAbstractSocket *socket = _server.nextPendingConnection();
QDataStream stream(socket, QIODevice::ReadWrite);
socket->waitForReadyRead(-1);
stream >> inQImage;
if (inQImage.isNull()){
qDebug("Received Image is empty");
}

Result:
libpng error: Read Error
Received Image is empty

Second Approach using the QImageWriter and QImageReader:
Client Side:


QImageWriter writer(socket, "png");
writer.write(image);
socket->waitForBytesWritten(-1);


Server Side:


_socket->waitForReadyRead(-1);
QImageReader imReader(_socket,"png");
imReader.read(_image);
_image.save("received.png","png");


The Result is also an libpng error: Read Error but the Image is partially transferred. When using a sufficiently small image it works.
It also works when the IODevice is not a QTcpSocket but a QFile

In both cases is seams that not all data is sent, is there a possibility that waitForBytesWritten() is not working as expected?

thanks in advance
Daniel

wysota
1st December 2009, 12:27
readyRead is emitted whenever there is any data available, not whenever there is all data available. Your image simply didn't fully arive just yet.

dfink
1st December 2009, 12:52
Thanks for the quick reply.

Shouldn't both the ImageReader and the >> operator check how big the picture is, and repeatedly read from the IODevice.
If not, has anyone a solution?

wysota
1st December 2009, 13:15
Shouldn't both the ImageReader and the >> operator check how big the picture is, and repeatedly read from the IODevice.
No they shouldn't. How should they know that no more data would come?


If not, has anyone a solution?
Send the size of the image before sending the image itself. Then continue waiting until there is enough data ready. Only then read the data from the socket.

dfink
2nd December 2009, 12:10
Thanks for the Hints, it finally works.
I used repeated Calls to readRawData(char* , int len) of QDataStream which did the trick.
What I find weird though is that using QDataStream & QDataStream::readBytes ( char *& s, uint & l ) didn't work at all.

wysota
2nd December 2009, 12:57
readBytes() and readRawBytes() do two completely different things so you can't exchange one for the other.

hkaraoguz84
23rd September 2010, 16:00
Hi,

This thread is a bit old but now I have the same problem.

I have connected the readyread signal to my slot but i cannot receive the whole image when readyread is emitted. I only receive 8192 bytes of. How can i make the program wait for whole to come? Is there any example code?

Thanks...