python服务端+Qt客户端实现TCP图像视频传输及显示完整代码,以及QImage::loadfromdata()方法失败的替代解决方案

2 篇文章 0 订阅
1 篇文章 0 订阅

话不多说,先看一下效果(python为服务器端,Qt为客户端)

在这里插入图片描述
左边是在python中用OpenCV显示的图像(RGB通道翻转过),右边是Qt接受数据后画出的图像,左下角是Qt发送到python的控制指令。

python服务器端实现

import socketserver
import socket
import cv2
import numpy as np
import threading

IMAGESIZE = 921600
IMAGEWIDTH = 640
IMAFEHEIGHT = 480
FRAMELENGTH = 1024

# 读取路径下的视频文件,以OpenCV打开
# 当然也可以打开摄像头
filepath = 'VideoTest.mp4'
cap = cv2.VideoCapture(filepath)
# 创建服务器
server = socket.socket()
# 获取到本机IP
PCname = socket.gethostname()
IP = socket.gethostbyname(PCname)
print(IP)
# 设置IP和端口号
server.bind((IP, 8082))
server.listen(1)

print('connecting...')


# 多线程接收数据
# socket接收为阻塞接收方式,阻断程序运行
# 用多线程的方式来避免发生阻塞
class Receive_Thread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.return_value = b'0'

    def run(self):
        while True:
            # 每次接收一个字节的数据
            self.return_value = cmd = conn.recv(1)

    # 返回接收到的数据
    def get_value(self):
        return self.return_value



while True:
    # 等待客户端连接
    # 阻塞方式,不连接不会执行下一步
    # conn为新创建的socket对象
    # 用于下边数据收发
    conn, addr = server.accept()
    print('收到请求')
    print('客户端地址', addr)
    # 创建数据接收线程
    rec_thread = Receive_Thread()
    rec_thread.start()
    while True:
        # 读取下一帧
        ret, frame = cap.read()
        # 数据类型为uint8
        framed = cv2.resize(frame, (IMAGEWIDTH, IMAFEHEIGHT))
        framed = cv2.cvtColor(framed, cv2.COLOR_BGR2RGB)
        has_sent = 0
        rec_data = rec_thread.get_value()
        # 打印接收到的控制指令
        if rec_data != b'0':
            print(rec_data)
        # 发送图片,每次发送1024字节
        while has_sent < IMAGESIZE:
            data_to_send = framed[has_sent: has_sent+FRAMELENGTH]
            conn.send(data_to_send)
            has_sent += FRAMELENGTH
        cv2.waitKey(100)
        cv2.imshow('jj', framed)
    break

cap.release()

到这里完成了TCPserver的部分,接下来在Qt中完成TCPClient的部分

Qt客户端实现

由于Qt代码较长,可以点击这里前往我的git主页下载
鉴于git网速较慢,也可以点击这里下载
根据其他博客,每一个部分基本都比较容易实现
但是又一个重要的一步是从Qbytearray转化到图片
在很多博客中都是通过QImage类的loadfromdata()来从数据获取图片
然而我测试n+1次仍未成功
后来采用了以下方法,其实很简单,只不过是不用loadfromdata函数来加载Qbytearray数据,而是改成了字符串:

void MainWindow::onSocketReadyRead()
{
    QByteArray bytes=NULL;
    while(Client->waitForReadyRead(100))
    {
        bytes.append((QByteArray)Client->readAll());
    }
    imagecount++;
    ReceiveCount->setText(QString::number(imagecount,10));
    // 网上大多数转换方法不对
    // uchar imagebuffer[IMAGESIZE];
    memcpy(imagebuffer, bytes, IMAGESIZE);
    image_receive=new QImage(imagebuffer, imagewidth,imageheight,QImage::Format_RGB888);
    DrawPainter->PassImage(*image_receive);
    DrawPainter->update();
}

至此整个程序完成

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值