1 将图片转为QByteArray传输
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
//pixmap不能为空,必须先将图片加载到pixmap中
pixmap.save(&buffer,"jpg");
QByteArray pixArray;
pixArray.append(buffer.data());
2 将QByteArray转为图片显示
QByteArray array;
while(client->waitForReadyRead(100)){
array.append((QByteArray)client->readAll());
}
QBuffer buffer(&array);
buffer.open(QIODevice::ReadOnly);
QImageReader reader(&buffer,"JPG");
QImage img = reader.read();
if(!img.isNull()){
QPixmap pix = QPixmap::fromImage(img);
ui->showImageLabel->setPixmap(pix.scaled(ui->showImageLabel->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}
视频发送端:
.h头文件:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv.hpp>
#include <QUdpSocket>
#include<QTimer>
using namespace cv;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void video_capture_send();
private:
Ui::MainWindow *ui;
VideoCapture camera;//
QUdpSocket sender;//
QTimer timer;//
QHostAddress dstip;//
quint16 dstport;//
};
#endif // MAINWINDOW_H
.cpp文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QBuffer> //
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QHostAddress srcip = QHostAddress::Any;//
quint16 srcport = 5555;
sender.bind(srcip,srcport);
dstip = QHostAddress("127.0.0.1");
//环回地址,等效于用本机IP,发给本机接收。
//可以用来测试本机的TCP/IP协议栈,数据包不会出网卡,网络设备不会对其做路由。
//localhost 是个域名,不是地址,它可以被配置为任意的 IP 地址,不过通常情况下都指向 127.0.0.1(ipv4)和 [::1](ipv6)
//localhost不能直接绑定套接字,必须先gethostbyname转成IP才能绑定
dstport = 6666;
//要跟接收方的一致
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
camera.open(0);
connect(&timer,SIGNAL(timeout()),this,SLOT(video_capture_send()));
timer.start(33);//结合上面,每隔33ms截屏一次并发送
}
void MainWindow::on_pushButton_2_clicked()
{
close();
}
void MainWindow::video_capture_send()
{
Mat frame;
//mat也是动态管理内存的数据类型
//也会尽量避免重复数据拷贝,(通过mat头),节省内存
//mat是三维数组,但也可通过二维数组初始化
camera.read(frame);
cvtColor(frame,frame,CV_BGR2RGB); //BGRtoRGB
//转换为常规的格式RGB
QImage image((unsigned char *)(frame.data),
frame.cols,frame.rows,
QImage::Format_RGB888);
//图像首地址是unsigned char *格式
//专用于读取IO图片数据
//Qpixmap专用于屏幕显示
//Qpicture是专用于执行QPianter指令作图的。
ui->label->setPixmap(QPixmap::fromImage(image));
ui->label->resize(image.width(),image.height());
// 进一步转换为Qpixmap用于屏幕显示
//调整为适应图像大小
QByteArray byte;
//字节数组 要进行传输必须先转换成这个格式
QBuffer buff(&byte);
// 建立一个用于IO读写(网卡)的缓冲区
//buff作为byte和IO设备的接口(显式)
// byte在内部作为一个与image的接口(隐式)
//操作都是对buff进行的,byte被隐藏
image.save(&buff,"JPEG");
// image先向下转为byte的类型,再存入buff
QByteArray ss = qCompress(byte,5);
//数据压缩算法,压缩比为5
QByteArray vv = ss.toBase64();
//数据加密算法
sender.writeDatagram(vv,dstip,dstport);
}
视频接收端:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void video_receive_show();
private:
Ui::MainWindow *ui;
QUdpSocket receiver;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QHostAddress>
#include<QPixmap>
#include<QImageReader>
#include<QBuffer>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QHostAddress localip= QHostAddress::Any;// both IPv4 and IPv6 interfaces
quint64 localport = 6666;
receiver.bind(localip,localport); //Binds to [address] on port [port]
//一般server才用bind(),客户端一般是自动选址
connect(&receiver,SIGNAL(readyRead()),this,SLOT(video_receive_show()));
//异步读取数据
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::video_receive_show()
{
quint64 size = receiver.pendingDatagramSize();
//直接读取异步监听时接收到的数据报
QByteArray buff;
// 字节矩阵,大小用qint64描述,适合操作1大量数据2字符串数组3二进制01数据,节省内存,更加安全
//一般用const char*初始化
// 默认采用深拷贝,可指定为浅拷贝
buff.resize(size);
//为缓冲区规定一个maxsize(没必要用那么大,刚好装下图像就够了)
receiver.readDatagram(buff.data(),buff.size());
// 数据报只支持一维操作
QBuffer buffer(&buff);
//提供用Qbytearray读写内存中IO缓存区的接口,若无传参内部默认自动创建一个Qbytearray;
//对IO缓存区读写操作等效于像IO设备读写数据
//操作QBuffer像在操作文件(其实原理都差不多,各自都是内存中一块特殊区域嘛)
QImageReader reader(&buffer,"JPG");
//可读入磁盘文件、设备文件中的图像、以及其他图像数据如pixmap和image,相比较更加专业。
//buffer属于设备文件一类,
//专业地读取设备文件的图像数据。
QImage image = reader.read();
//read()方法用来读取设备图像,也可读取视频,读取成功返回QImage*,否则返回NULL
//格式转换
ui->label->setPixmap(QPixmap::fromImage(image));
ui->label->resize(image.width(),image.height());
}