此文用于记录Qt远程采集摄像头画面的办法,以备忘记,Qt远程采集画面可以实现远程监控,视频通话和一些远程识别功能;本次以TCP作为通信手段,实现传输功能,Qt版本使用15.5.2。,实现原理为照片不间断地传输和显示,让人眼分辨不出来,即可实现在线视频监控。
一,视频发送端的实现
1.1实现通信界面,界面由如下几部分组成
最终的界面如下:
1.2TCP服务器的实现,Qt下TCP服务器的实现很简单,直接调用QTcpServer的方法,进行监听
关联信号的和槽函数,实现监听处理
槽函数的实现,槽函数中使用一个定时器,定时50ms,每50ms出发一次cap_pic和transfer_pic函数,实现拍照和传输照片
transfer_pic槽函数的实现,此处使用img.save实现照相机拍照到的图片的压缩,方便TCP一次性的传输,当图片大于70KB左右时,一次传输不过去,所以这里实现和图片的压缩再传输。
1.3摄像头及拍照的实现,摄像机相关的类及操作和拍照的槽函数如下,正常操作,无注意点,直接实现即可。
cap_pic槽函数
还有一点注意的是开关摄像头的槽函数,关闭摄像头是需要关闭定时器,让TCP不再发送图片过去。
二,视频接受端的实现
2.1界面的实现,界面无需设计太多,满足功能要求即可,做一个Qlabel即可。
2.2TCP客户端的搭建,直接调用Qt相关的类和函数即可
此处由一个槽函数,当客户端收到消息的时候,执行play_movie函数
play_movie函数如下,每次接受到图片,就覆盖掉上一次接受到的图片,然后重新显示到QLabel上,实现快速更新,使人肉眼分辨不出来是图片,即可实现诗篇的显示。
三,此上为摄像头在线显示的全过程,最终界面成果如下:
最后,贴出源码,方便以后复制粘贴
//***************************************视频发送端头文件
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void init_ui();
public:
QCamera *cam;
QCameraViewfinder *vf;
QCameraImageCapture *imc;
QTextEdit *te;
QPushButton *but_open_cam;
QPushButton *but_close_cam;
QHBoxLayout *hb1;
QVBoxLayout *vb1;
QTcpServer *ser;
QTcpSocket *mycli;
QTimer *tim;
QCameraImageCapture *imgcap;
public slots:
void open_cam();
void close_cam();
void cap_pic();
void connect_success();
void transfer_pic();
};
#endif // WIDGET_H
//********************************************视频发送端.cpp文件
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->tim=new QTimer();
this->cam=new QCamera(QCameraInfo::defaultCamera());
//this->cam->setCaptureMode(QCamera::CaptureStillImage);
this->imgcap=new QCameraImageCapture(this->cam);
this->init_ui();
this->ser=new QTcpServer();
this->ser->listen(QHostAddress::AnyIPv4,8888);
connect(this->but_open_cam,&QPushButton::clicked,this,&Widget::open_cam);
connect(this->but_close_cam,&QPushButton::clicked,this,&Widget::close_cam);
connect(this->ser,&QTcpServer::newConnection,this,&Widget::connect_success);
}
Widget::~Widget()
{
}
void Widget::init_ui()
{
this->vf=new QCameraViewfinder();
this->vf->setFixedSize(400,250);
this->cam->setViewfinder(this->vf);
this->vf->show();
this->te=new QTextEdit();
this->but_open_cam=new QPushButton(tr("打开摄像头"));
this->but_close_cam=new QPushButton(tr("关闭摄像头"));
this->hb1=new QHBoxLayout();
this->vb1=new QVBoxLayout();
this->hb1->addWidget(this->but_open_cam);
this->hb1->addWidget(this->but_close_cam);
this->vb1->addWidget(this->vf);
this->vb1->addWidget(this->te);
this->vb1->addLayout(this->hb1);
this->setLayout(this->vb1);
}
void Widget::open_cam()
{
this->cam->start();
}
void Widget::close_cam()
{
this->tim->stop();
this->cam->stop();
}
void Widget::connect_success()
{
this->mycli=this->ser->nextPendingConnection();
this->te->setText(tr("连接成功"));
connect(this->tim,&QTimer::timeout,this,&Widget::cap_pic);
connect(this->tim,&QTimer::timeout,this,&Widget::transfer_pic);
this->tim->start(50);
}
void Widget::cap_pic()
{
this->imgcap->capture("D:/QTfile/pic_tranfer/pic/1");
}
void Widget::transfer_pic()
{
qDebug()<<"--------------";
QImage img("D:/QTfile/pic_tranfer/pic/1.jpg");
img.save("D:/QTfile/pic_tranfer/pic/1.jpg","jpg",20);
QFile file("D:/QTfile/pic_tranfer/pic/1.jpg");
file.open(QIODevice::ReadOnly);
QByteArray tem=file.readAll();
file.close();
this->mycli->write(tem);
}
//******************************************视频接收端头文件
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public:
QHBoxLayout *hb;
QLabel *lb;
QTcpSocket *mysocket;
public slots:
void play_movie();
};
#endif // WIDGET_H
//*******************************************视频接收端.cpp文件
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->lb=new QLabel();
this->lb->setFixedSize(400,250);
this->hb=new QHBoxLayout();
this->hb->addWidget(this->lb);
this->setLayout(this->hb);
this->mysocket=new QTcpSocket();
this->mysocket->connectToHost("192.168.17.1",8888);
connect(this->mysocket,&QTcpSocket::readyRead,this,&Widget::play_movie);
}
Widget::~Widget()
{
}
void Widget::play_movie()
{
QByteArray data=this->mysocket->readAll();
QFile file("D:/QTfile/pic_tranfer/pic_recv/1.jpg");
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
file.write(data);
file.close();
QImage image("D:/QTfile/pic_tranfer/pic_recv/1.jpg");
QPixmap pic=QPixmap::fromImage(image);
this->lb->setPixmap(pic.scaled(this->lb->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}