2014-06-24 2 views
2

센서에서 이미지를 표시하기 위해 GUI 작업을하고 있습니다. GUI는 센서가 서버 역할을하는 동안 클라이언트 역할을합니다. 일단 센서에 명령을 보내면 센서는 TCP를 통해 스트리밍 원시 이미지 데이터 (바이너리 데이터)를 GUI로 계속 전송합니다. 데이터는 크기 너비 (1240) x 높이 (1028)가 U8 (부호없는 8 비트)으로 코딩 된 이미지 메모리의 정확한 사본입니다. 수신 데이터의 크기는 (1240 x 1028 x 1 바이트) + 20 바이트 (메타 헤더) = 1.3MB입니다.Qt를 사용하여 표시하기 위해 TCP를 통해 원시 이미지 데이터를 수신합니다.

내 가장 큰 장애물은 다음과 같습니다. 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 

"client.cpp"

#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; 
} 
+0

클래스가 'QTcoSocket'가 있습니다 데이터 프로세서에 연결할 수있는 incessant [readyRead()] (http://qt-project.org/doc/qt-4.8/qiodevice.html#readyRead) 신호. 원시 데이터를 표시하기 위해 [이 스레드] (http://stackoverflow.com/questions/9797862/qt-c-converting-raw-binary-data-and-display-it-as-an-image-ie-qimage) 너를 도울지도 모른다. – Tay2510

답변

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!"; 
    } 
} 
+0

각 스캔마다 수신 할 응답 데이터는 다음과 같습니다. <카운터 (4 바이트)><너비 (4 바이트)>><높이 바이트)> 먼저 Cmd_ID 값이 예상 값과 일치하는지 확인해야합니다. 그런 다음 너비와 높이를 곱하여 이미지 데이터의 크기를 계산해야합니다. 일반적으로 이미지 데이터의 크기는 1280 x 1024 바이트 = 1.3 바이트입니다. 제 경우에 tcpReady()를 어떻게 적용 할 수 있습니까? 데이터를 읽으려는 방법을 사용했지만 QImage는 NULL을 반환합니다. 그 원인은 무엇일까? – user3769908

+0

헤더를 읽은 다음에, width와 height를 읽어서 : stream >> imageWidth >> imageHeight;'를 읽고 곱해서 dataSize를 얻으십시오. – Nejat

+0

감사합니다. 그것은 일하고있다 !!! – user3769908

관련 문제