QT+Opencv视频文件TCP网络传输

来源:互联网 发布:顶级网络12职业传奇 编辑:程序博客网 时间:2024/04/30 13:45

这几天一直在看TCP网络这块,希望实现网络摄像头实时监控,现在实现了一个基本的demo,以后将在这个基础上实现更多的功能,在这里我是在客户端传送视频,然后在服务器显示。
前面我还写了一个基本的UDP消息传输:http://blog.csdn.net/u013812682/article/details/52149665,有兴趣的可以看看交流,不多说了,看效果和代码。

客户端:

效果图:
这里写图片描述
代码:
client.h

#ifndef CLIENT_H#define CLIENT_H#include <QWidget>#include<QtNetwork>#include<QTcpServer>#include<QTcpSocket>#include<QImage>#include<QImageReader>#include<QTime>#include<QDebug>#include<QMessageBox>#include<QFileDialog>#include<opencv2/highgui/highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<opencv2/core/core.hpp>using namespace cv;namespace Ui {class Client;}class Client : public QWidget{    Q_OBJECTpublic:    explicit Client(QWidget *parent = 0);    ~Client();    qint64 blockSize;    QTcpSocket* tcpSocket;    VideoCapture cap;    QTimer* timer;private slots:    void displayError(QAbstractSocket::SocketError);    void requestNewFortune();    void enableGetFortuneButton();    void SendData();private:    Ui::Client *ui;};#endif // CLIENT_H

client.cpp

#include "client.h"#include "ui_client.h"Client::Client(QWidget *parent) :    QWidget(parent),    ui(new Ui::Client){    ui->setupUi(this);    ui->Fortune_ptn->setGeometry(10,30,40,40);    ui->quit_ptn->setGeometry(100,30,40,40);    tcpSocket=new QTcpSocket(this);    timer=new QTimer(this);    cap.open("test.avi");    if(!cap.isOpened()){        QMessageBox::information(this,tr("提示"),tr("视频没有打开"));    }    connect(ui->Fortune_ptn,SIGNAL(clicked(bool)),this,SLOT(requestNewFortune()));    connect(ui->quit_ptn,SIGNAL(clicked(bool)),this,SLOT(enableGetFortuneButton()));    connect(timer,SIGNAL(timeout()),this,SLOT(SendData()));    connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));}Client::~Client(){    delete ui;}void Client::displayError(QAbstractSocket::SocketError){    qDebug()<<"传输失败!";}void Client::requestNewFortune(){    timer->start(30);    ui->Fortune_ptn->setEnabled(true);}void Client::enableGetFortuneButton(){    ui->Fortune_ptn->setEnabled(true);    tcpSocket->disconnectFromHost();    timer->stop();}void Client::SendData(){    blockSize=0;    tcpSocket->abort();    tcpSocket->connectToHost(QHostAddress::LocalHost,8888);    Mat frame;    cap>>frame;    cvtColor(frame,frame,CV_BGR2RGB);    QByteArray byte;    QBuffer buf(&byte);    QImage image((unsigned const char*)frame.data,frame.cols,frame.rows,QImage::Format_RGB888);    image.save(&buf,"JPEG");    QByteArray ss=qCompress(byte,1);    QByteArray vv=ss.toBase64();    QByteArray ba;    QDataStream out(&ba,QIODevice::WriteOnly);    out.setVersion(QDataStream::Qt_5_6);    out<<(quint64)0;    out<<vv;    out.device()->seek(0);    out<<(quint64)(ba.size()-sizeof(quint64));    tcpSocket->write(ba);    ui->image_label->setPixmap(QPixmap::fromImage(image));    ui->image_label->resize(image.size());    update();}

服务器端:

效果图:
这里写图片描述

代码:
server.h

#ifndef SERVER_H#define SERVER_H#include <QWidget>#include<QTcpSocket>#include<QTcpServer>#include<QString>#include<QtNetwork>#include<QMessageBox>#include<QImage>namespace Ui {class Server;}class Server : public QWidget{    Q_OBJECTpublic:    explicit Server(QWidget *parent = 0);    ~Server();    QTcpServer *tcpServer;    QTcpSocket *tcpServerConnection;    QStringList *fortunes;    QImage *img;    quint64 basize;public slots:    void sendFortune();    QByteArray GetPicData(QString fromPic);    void DisplayError(QAbstractSocket::SocketError socketError);    void ReadMyData();    void ShowImage(QByteArray ba);private:    Ui::Server *ui;};#endif // SERVER_H

server.cpp

#include "server.h"#include "ui_server.h"Server::Server(QWidget *parent) :    QWidget(parent),    ui(new Ui::Server){    ui->setupUi(this);    tcpServer = new QTcpServer(this);    if(!tcpServer->listen(QHostAddress::Any,8888))    {        QMessageBox::critical(this,tr("Fortune Server"),tr("Unable to start the server:%l.").arg(tcpServer->errorString()));        close();        return;    }    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));}Server::~Server(){    delete ui;}void Server::sendFortune(){    basize=0;    tcpServerConnection = tcpServer->nextPendingConnection();    connect(tcpServerConnection,SIGNAL(readyRead()),this,SLOT(ReadMyData()));    connect(tcpServerConnection,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(DisplayError(QAbstractSocket::SocketError)));}QByteArray Server::GetPicData(QString fromPic){    QImage img(fromPic);    QByteArray block;    QBuffer buf(&block);    img.save(&buf,"JPEG");//按照JPG解码保存数据    QByteArray cc = qCompress(block,1);    QByteArray hh;    hh=cc.toBase64();//base64数据    return hh;}void Server::DisplayError(QAbstractSocket::SocketError socketError){    tcpServerConnection->close();}void Server::ReadMyData(){    QByteArray message;//存放从服务器接收到的字符串    QDataStream in(tcpServerConnection);    in.setVersion(QDataStream::Qt_5_6);    if (basize==0)    {        //判断接收的数据是否有两字节(文件大小信息)        //如果有则保存到basize变量中,没有则返回,继续接收数据        if (tcpServerConnection->bytesAvailable()<(int)sizeof(quint64))        {            return;        }        in>>basize;    }    //如果没有得到全部数据,则返回继续接收数据    if (tcpServerConnection->bytesAvailable()<basize)    {        return;    }    in>>message;//将接收到的数据存放到变量中    ShowImage(message);}void Server::ShowImage(QByteArray ba){    QString ss=QString::fromLatin1(ba.data(),ba.size());    QByteArray rc;    rc=QByteArray::fromBase64(ss.toLatin1());    QByteArray rdc=qUncompress(rc);    QImage img;    img.loadFromData(rdc);    ui->image_label->setPixmap(QPixmap::fromImage(img));    ui->image_label->resize(img.size());    update();}

后期我将尝试云服务器端的服务器与本地客户端实现,如果有同学希望一起交流可以留言给我,也可以发我邮箱,dearbigboy@163.com.

0 0
原创粉丝点击