socket传输图片之TCP协议

2023-11-18

在学习socket传输图片之前,我们应该先具备一些基础知识。

opencv图片编码和解码

cv2.imencode()
cv2.imdecode()

这两个函数是本教程再传输图片会用到的。个人粗浅的理解是放在内存的中的图片是以图像数据的形式存放的,而它们的后缀.jpg或.png决定的是它们在传输过程中的形式以及它们从原来的原始数据被压缩过来的方式。简而言之,jpg、png(图像格式)是一个中间量,而不是一个状态量。可以理解为jpg通道之类的。
那么我们在用socket传输的时候就必须先把图像数据转化为图像格式。

#读取图像数据
image = cv2.imread("path/1.jpg")
#把图像数据转化为jpg格式(理解为打开jpg通道),至于以下参数什么意思,自行百度
img_encode = cv2.imencode('.jpg',img,[cv2.IMWRITE_JPEG_QUALITY, 99])

对应的解码和打开

img_decode = cv2.imdecode(img_encode, cv2.IMREAD_COLOR)
cv2.imshow("photo",img_decode)
cv2.waitkey(0)

tcp协议数据传输限制

tcp协议里面规定我们一次最多只能传输1024bytes(字节)的数据,但对于一张图片来说1024bytes实在是太少了,所以我们得分批传过去,然后再分批接收,但接收方如何知道到底要接收几个字节的数据呢?答案是定义一个结束标志位,这听起来是个麻烦的过程,但代码执行起来确十分轻松。
请看例程:

#发送端,发送字节长度+结束标志位
flag_data = (str(len(bytedata))).encode() + "end".encode()

解释一下,对于太大的数据,接收端必须先知道要即将会接收几个字节的数据,然后再开始进行内容的接收,而且发送的数据必须经过编码,至于为什么,这里不做探究。所以(str(len(bytedata)))代表即将发送的数据的长度,"end"为结束标志位。这里有点绕哈,不过理解了这个接下来的东西就没问题了。

#接收端,解码并且获取字节长度
flag = flag_data.decode().split("end")[0]
total = int(flag)

正式编成的一些重要板块

接下来的逻辑是:一:接收端到知道即将要接收多少个字节,做好准备,告诉发送端可以发送正式的数据(图片数据)了
二:发送端接收到可以发送的信号,开始发送数据。

#接收端
tcp.send(b"ok")
count = 0 
end_data = b""            #定义一个存储字节流的变量
while count < total:
	data = tcp.recv(1024)
	end_data += data           #end_data就是最终的图片数据
	count += len(data)
#为了能在Nms内发送N张图片,修改一下上面的读取程序
count = 0
temp = 1024
while count < total:
	data = tcp.recv(temp)
	end_data += data
	count += len(data)
	if (count+1024) > total:
		temp = total - count       #防止读取到下一次数据的包头

依旧啰嗦一下,TCP都是以字节流的形式进行传输的,所以end_data得到的是完整图片的字节流形式,我们解码之后才可以使用。但是opencv只能解码uint8格式的数据,所以我们还需要先将其转化为为uint8格式的数据。

#接收端解码
#字节流->uint8格式->opencv解码->完整图像
img = np.asarray(bytearray(end_data), dtype="uint8")   
img = cv2.imdecode(img, cv2.IMREAD_COLOR)

这个地方与我最开始说的解码编码不同,因为最开始没有把字节流传输这一块包含进去,cv2.imencode()出来的图像还不是字节流。所以真实的编码应当是这样的:

#发送端编码
img = cv2.imread("D:/pp-ocr/PaddleOCR/train_data/text_trian/1.jpg")
img_encode = cv2.imencode('.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 99])[1] 
byte_data = img_encode.tobytes() #转化为字节流

ok,讲到这里大家也大概成功混乱了吧,待我都讲完为大家理清思绪。在上面我提到
“发送端接收到可以发送的信号,开始发送数据”
我们来看看它的代码:

#发送端接收到ok的信号,开始发送数据
if ("ok" == rec.decode()):   
    socket_tcp.send(byte_data)

理清思绪,就参考这篇文章咯

https://blog.csdn.net/qq_42688495/article/details/108279618

最后也附上这两天刚看到的文章,可以一次性传输图片。

https://blog.csdn.net/qq_24282081/article/details/106498871

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

socket传输图片之TCP协议 的相关文章

随机推荐

  • angular中组件之间的嵌套使用

    第一步先把对应的文件创建好 main component ts phone component ts books component ts details component ts 第二步 导入到我们的app module文件中 impor
  • pip修改下载源

    Windows 直接切换到虚拟环境中 输入下面的命令即可 配置中科大镜像 pip config set global index url https mirrors ustc edu cn pypi web simple 配置阿里源 pip
  • java实现一个整数和一个小数的四则运算和求最大值,平均值。

    实现一个整数和一个小数的四则运算和求最大值 平均值 import java applet Applet import java awt public class Yunsuan extends Applet Label prompt1 pr
  • verilog中$readmemb和$readmemh的使用

    菜鸟一枚 只是分享一下在学习的过程 和这两个系统函数的简单用法 readmemb和 readmemh用来从文件中读取数据到存储器中 读取的内容只包括 空白位置 空格 换行 制表格 tab和form feeds 注释行 二进制或十六进制的数字
  • 微信小程序后端,helloworld,a+b,JSONObject相关问题。

    参考视频教程 b站 P5 输出hello world 按视频教程敲 即可 小程序输入数字 IDEA运算后返回A B 小程序开发工具中代码 IDEA中代码 教程 所遇到问题 解决 输入后 找不到getInteger方法 检查发现 是我类的问题
  • 用html+css给女朋友写一个爱心

    这是最后的样子 用一个div 再用before和after就行了 这是html div class ax div 再加上css padding 0px margin
  • 华为OD机试 - 字符串排序(C++ & Java & JS & Python)

    目录 描述 输入描述 输出描述 示例1 Java python C 描述 编写一个程序 将输入字符串中的字符按如下规则排序 规则 1 英文字母从 A 到 Z 排列 不区分大小写 如 输入 Type 输出
  • jdbc(2)——之Class.forName(com.mysql.cj.jdbc.Driver)理解

    理解Class forName Com mysql cj jdbc Driver Class forName com mysql cj jdbc Driver 在使用jdbc的时候这行代码必不可少 我们来仔细理解一下这行代码的意义和原理 1
  • 毕业设计 免费送源码36412-SSM 环卫人员管理平台,【计算机毕业设计开题选题+程序定制+论文书写+答辩ppt书写-原创(题目+编号)的定制程序】

    本科生毕业论文 设计 题 目SSM环卫人员管理平台 学 院 XXXXX 专业班级 XXXXX 用户姓名 XXXX 指导人才招聘 XXXX 撰写日期 2023年3月 目 录 摘要 1 绪论 1 1背景及意义 1 2国内外研究概况 1 3研究内
  • 列举几个:MAC OS科研软件推荐

    工欲善其事 必先利其器 部分科研狗也会深爱MAC OS虽然他再科研软件上跟WINDOWS相比还有一定差距 但是MAC OS的人性化轻量也是深得人心 这次就为大家推荐MAC OS上的科研软件 1 科学绘图软件 QtiPlot SciDAVis
  • CS5216

    CS5216特点 DP 到HDMI的显示协议转换器 支持Level shifter Repeater两种应用 应用Dongle或Cable市场 将显卡DP 输出 转接为HDMI输出 CS5216参数 符合高达3 0Gbps的HDMI 1 4
  • Linux之prink原理

    我的分析是基于Linux4 15 1 1 看看kernel是如何调用到console初始化函数的 分两条线 a start kernel gt console init gt call con initcall start 去调用放在 co
  • Java 集合、HashMap 底层实现原理

    一 Java 集合概述 Java 集合可分为 Collection 和 Map 两种体系 Collection接口 单列数据 定义了存取一组对象的方法的集合 List 元素有序 指的是存储时 与存放顺序保持一致 可重复的集合 Set 元素无
  • Mybatis---增删改查

    目录 一 添加用户 1 持久层接口方法 2 映射文件 3 测试方法 二 修改用户 1 持久层接口方法 2 映射文件 3 测试方法 三 删除用户 1 持久层接口方法 2 映射文件 3 测试方法 四 查询用户 1 持久层接口方法 2 映射文件
  • Redis查询当前库有多少个 key

    info可以看到所有库的key数量 dbsize则是当前库key的数量 keys 这种数据量小还可以 大的时候可以直接搞死生产环境 dbsize和keys 统计的key数可能是不一样的 如果没记错的话 keys 统计的是当前db有效的key
  • C++面试题之继承

    目录 设计一个类型 不能在外部环境中创建该类的对象 设计一个不能被继承的类 设计一个不能被继承的类 但可以在外部环境创建该类型的对象 设计一个能被继承的类 但不能在外部环境创建该类型的对象 限制派生类对象不可以拷贝和赋值如何实现 设计一个类
  • Git(五):历史提交与远程仓库修改

    目录 4 查看提交历史 4 1 查看日志详细信息 4 2 查看某次提交信息 4 3 查看更改 5 撤销操作 5 1 取消暂存的文件 5 2 撤销对文件的修改 5 3 撤销远程记录 6 远程仓库的使用 6 1 查看远程仓库 6 2 添加远程仓
  • Python自动化部署环境

    import paramiko import sys 创建SSHClient实例对象 ssh paramiko SSHClient 调用方法 表示没有存储远程机器的公钥 允许访问 ssh set missing host key polic
  • 全球及中国冷链物流产业需求前景与投资竞争力研究报告2022版

    全球及中国冷链物流产业需求前景与投资竞争力研究报告2022版 HS HS HS HS HS HS HS HS HS HS HS HS 修订日期 2021年11月 搜索鸿晟信合研究院查看官网更多内容 第一章 冷链物流相关概述 1 1 冷链物流
  • socket传输图片之TCP协议

    在学习socket传输图片之前 我们应该先具备一些基础知识 opencv图片编码和解码 cv2 imencode cv2 imdecode 这两个函数是本教程再传输图片会用到的 个人粗浅的理解是放在内存的中的图片是以图像数据的形式存放的 而