Bild über QTcpSocket senden



  • Hallo

    Ich versuche momentan ein Bild(Einfachheit halber ein Desktop Screen) über einen QTcpSocket zu senden. Das Senden scheint zu gehen(Debug Ausgaben). Nur beim Empfangen ist irgend etwas falsch. Die Grösse im QByteArray ist jedes mal total falsch? Wieso weiss ich auch nicht. Und genau da brauche ich eure Hilfe. Hat jemand eine Idee, warum das QByteArray nie die richtige grösse hat?

    Das Bild empfangen tue ich so:

    /* In this->nextReadSize ist die grösse des Bildes(Bytes)
                In this->clientSBin ist ein QTcpSocket
                In bytes (oder this->bytes) ist ein QByteArray(als Datenfeld)
               In  this->streamCom ist auch ein QTcpSocket von diesem Socket kommt die Grösse des bildes
            */
            this->streamCom >> this->nextReadSize;
            qDebug() << "Neue Daten zum lesen" << this->nextReadSize;
    
            QBuffer buffer(&bytes);
    	buffer.open(QIODevice::ReadWrite);
    
    	char *buff = new char[1024];
    	// empfange solange, wie bild nicht vollständig empfangen 
    //oder keine daten mehr im Socket vorhanden sind	while(this->nextReadSize > 0 && this->clientSBin->bytesAvailable())
    	{
    			int read = this->clientSBin->read(buff, 1024);
    			buffer.write(buff, read);
    			this->nextReadSize = this->nextReadSize - read;
    			qDebug() << "noch zu Lesen:" << this->nextReadSize;
    	}
    
    	// bild vollständig empfangen?
    	if(this->nextReadSize == 0)
    	{
    
    		qDebug() << "Alle Daten gelsesen; groesse bytes:" << this->bytes.size();
    
    		QPixmap pixmap;
    		pixmap.loadFromData(this->bytes, "PNG");
    		emit neuesBildEmpfangen(pixmap);
    		this->bytes.clear();
    	}
    

    Senden so:

    QPixmap pixmap = Util::shootScreen();
    	emit gesendetesBild(pixmap);
    
    	QByteArray bytes;
    	QBuffer buffer(&bytes);
    	buffer.open(QIODevice::ReadWrite);
    	pixmap.save(&buffer, "PNG");
    	buffer.seek(0);
    
    	qint32 size = bytes.size();
    	this->streamCom << size;
    	qDebug() << "Sende Grösse:" << size;
    
    	char *buff = new char[1024];
    	int count = 0;
    	while(buffer.bytesAvailable() != 0)
    	{
    		int read = buffer.read(buff, 1024);
    		int sent = this->clientSBin->write(buff, read);
    		count += sent;
    		qDebug() << "gesendet:" << count;
    	}
    	this->clientSBin->waitForBytesWritten();
    

    Unter http://www.megaupload.com/?d=GQOD4POY ist der Ganze Quelltext ersichtlich.

    mfg planetenkiller



  • wieso spielst du eigentlich von hand mit den buffern rum?

    QTcpSocket ist ein QIODevice. du kannst also einfach ein QDataStream darauf legen. sieht dann zum schreiben so aus:

    QPixmap pixmap(von_irgendwo);
    QDataStream socketstream(tcpsocket); //QTcpSocket* tcpsocket;
    socketstream << pixmap;
    

    und zum lesen:

    QPixmap pixmap;
    QDataStream socketstream(tcpsocket);
    socketstream >> pixmap;
    

    ich denk, das ist deutlich einfacher als die buffer von hand zum führen. ich würde dir sowieso empfehlen den tcpsocket, wenn du größere mengen daten schreiben/lesen willst, immer in einen datastream zu packen.



  • Ich wusste gar nicht, dass QDataStream QPixmap senden kann...cool

    Ich erhalte allerdings beim Empfangen des Bildes immer den Fehler:
    libpng error: Read Error
    Leider hilft mir diese Fehlerbeschreibung auch nicht weiter. libpng konnte das bild wohl nicht lesen 😕 😞

    mfg planetenkiller



  • das ist seltsam. sollte eigentlich so funktionieren. probiere das doch bitte mal mit einer datei statt des tcpsocket aus, um auszuschließen, dass da ein fehler im dem stream-opertator der qpixmap liegt.



  • Das geht irgendwie auch nicht? 😮 So habe ich es Probiert:

    Bild Speichern:

    QPixmap pixmap = Util::shootScreen();
    emit gesendetesBild(pixmap);
    QFile *datei = new QFile("test.dat");
    QDataStream stream;
    stream.setDevice(datei);
    stream << pixmap;
    datei->waitForBytesWritten(-1);
    datei->close();
    

    Bild Laden:

    QPixmap pixmap;
    QFile *datei = new QFile("test.dat");
    QDataStream stream;
    stream.setDevice(datei);
    datei->open(QIODevice::ReadOnly);
    stream >> pixmap;
    qDebug() << "Bild geladen h:" << pixmap.height() << " w:" << pixmap.width();
    emit neuesBildEmpfangen(pixmap);
    

    Ausgabe des qDebug();
    Bild geladen h: 0 w: 0
    QPixmap::scaled: Pixmap is a null pixmap

    hmm, irgend etwas muss bei mir gewaltig schief laufen. 😞 Ubuntu kann die geschriebene Datei ohne Probleme Anzeigen.
    mfg planetenkiller
    PS:



  • das öffnen der datei und des stream muss andersherum erfolgen. desweiteren hat der stream eine ctor, der QIODevices annimmt.

    QPixmap pixmap;
    QFile *datei = new QFile("test.dat");
    datei->open(QIODevice::ReadOnly);
    QDataStream stream(datei);
    stream >> pixmap;
    qDebug() << "Bild geladen h:" << pixmap.height() << " w:" << pixmap.width();
    emit neuesBildEmpfangen(pixmap);
    

    das sollte eigentlich gehen. wenn ein normales programm unter ubuntu das aufbekommt, stehe ich vor einem rätsel, warum es durch den tcpsocket nicht gehen sollte.



  • Es hat sich nichts geändert, geht immer noch nicht.

    ...warum es durch den tcpsocket nicht gehen sollte.

    Ich denke, wenn es mit Dateien nicht geht, wird es mit sockets ebenso schwierig.

    ...wenn ein normales programm unter ubuntu das aufbekommt....

    Wiso eigentlich? In der Doku zu QPixmap steht:

    Note that writing the stream to a file will not produce a valid image file.

    Ubuntu scheint es doch irgendwie zu schaffen, das Bild anzuzeigen 😕

    *Edit*
    Mit

    QPixmap pixmap;
    pixmap.load("test.dat", "PNG");
    qDebug() << "Bild geladen h:" << pixmap.height() << " w:" << pixmap.width();
    emit neuesBildEmpfangen(pixmap);
    

    kann er das Bild ohne Probleme laden und es wid auch angezeigt? 😮
    LOL C++ und Qt sind ja cool, die halten einem auf trapp 🕶 Es wird das unmöglichste möglich.


Anmelden zum Antworten