通过TCP接收原始图像数据以使用Qt显示

时间:2014-06-24 06:39:20

标签: qt tcp

我正在使用GUI来显示来自传感器的图像。 GUI充当客户端,而传感器充当服务器。一旦我向传感器发送命令,传感器将通过TCP将流式原始图像数据(二进制数据)连续发送到GUI。数据将是图像存储器的精确副本,其大小宽度(1240)x高度(1028)以U8(无符号8位)编码。一个输入数据的大小为(1240 x 1028 x 1字节)+ 20字节(元标题)= 1.3 MByte。

我最大的障碍是: 1.)如何连续接收和存储来自传感器的流数据以用于显示目的? 2.)如何显示原始数据?

我已尝试过如下代码,但它无效。请指教:

" client.h"

#ifndef CLIENT_H
#define CLIENT_H

#include <QObject>
#include <QWidget>
#include <QTcpSocket>

class Client : public QWidget
{
    Q_OBJECT
public:
    explicit Client(QWidget *parent = 0);
    int capture (int mode, int NBRLine);

signals:

public slots:

private:
    QTcpSocket* socket;

};

#endif // CLIENT_H

&#34; client.cpp&#34;

#include "client.h"
#include <QHostAddress>
#include "mainwindow.h"
#include <QtGui>
#include <QAbstractSocket>
#include <QImage>

Client::Client(QWidget *parent) :
    QWidget(parent)
{
    socket = new QTcpSocket(this);  
}

int Client::capture(int mode, int NBRLine)
{
    if (socket->state() != QTcpSocket::ConnectedState)
    {
        socket->connectToHost("192.168.0.65", 1096);
    }

    /* send command to retrieve raw image data from sensor */
    if(socket->waitForConnected(5000))
    {
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_0);
        out.setByteOrder(QDataStream::LittleEndian);
        out << qint32(0) << qint32(0) << qint32(0) << qint32(1);
        out << qint32(9) << qint32(1) << qint32(0) << mode << qint32(10) << qint32(2) << qint32(0) << NBRLine ;
        socket->write(block);
        socket->flush();
    }
    else
    {
        return false;
    }
    /**********************************************************/

    /* to get data size of each scan through width and height in the meta header */
    QDataStream input(socket);
    input.setVersion(QDataStream::Qt_4_0);
    input.setByteOrder(QDataStream::LittleEndian);
    qint32 buffer, cmdID, counter, metaSize, width, height;
    do
    {
        if (socket->waitForReadyRead(1000))
        {
            input >> cmdID;
            if (cmdID == 101)
            {
                input >> buffer >>  buffer >> buffer >> buffer;
            }
        }
        else
        {
            socket->disconnectFromHost();
            break;

        }
    } while (cmdID != 1);

    input >> counter >> metaSize;
    if (metaSize != 8) return false;

    input >> width >> height;
    quint32 datasize =  width * height;

    /**********************************************************/

    /* Receiving streaming data which I have problem here !!!! */
    while (socket->bytesAvailable() < datasize + 80) {
        if (!socket->waitForReadyRead(1000)) {
            socket->disconnectFromHost();
            break;
        }
    }

    QImage img;
    input >> img;

    if (img.isNull())
    {
        return 0;
    }
    img.save("E:/temp1");
     return 1;
}

1 个答案:

答案 0 :(得分:2)

在发送缓冲区内容之前,您需要找到一种方法来告诉客户端需要多少数据。首先,您应该发送数据大小,然后发送数据。

在服务器端,您应该发送图像数据,如:

QTcpSocket socket;

QBuffer buffer;
QImageWriter writer(&buffer, "PNG");
writer.write(QImage("myImage.png") );

QByteArray data;
QDataStream stream( &data, QIODevice::WriteOnly );
stream.setVersion( QDataStream::Qt_4_8 );
stream << (quint32)buffer.data().size();
data.append( buffer.data() );

socket.write( data );

在客户端,您应该将套接字的readyRead信号连接到插槽,以便在收到新数据时读取数据:

connect( socket, SIGNAL(readyRead()),this, SLOT(tcpReady()) );

图像数据可以像:

一样读取
void Client::tcpReady()
{
    if( dataSize == 0 )
    {
        QDataStream stream( &socket );
        stream.setVersion( QDataStream::Qt_4_8 );

        if( socket.bytesAvailable() < sizeof(quint32) )
            return;

        stream >> dataSize;
    }

    if( dataSize > socket.bytesAvailable() )
        return;

    QByteArray array = socket.read( dataSize );
    QBuffer buffer(&array);
    buffer.open( QIODevice::ReadOnly );

    QImageReader reader(&buffer, "PNG");
    QImage image = reader.read();

    if( !image.isNull() )
    {
        image.save("E:/temp1");
    }
    else
    {
        QDebug()<<"Invalid image received!";
    }
}