【Python】socket传输图像

2022-08-23 12:25:47

客户端截屏传给服务器端


客户端

# -*- coding: utf-8 -*-import socket, struct, pyscreenshot, gzipfrom PILimport Imagefrom ioimport BytesIOclassCLIENT():def__init__(self):
		self.bufSize=10240# 每一次传输的字节流长度defData(self, s):whileTrue:
			img= pyscreenshot.grab()# 截取屏幕图像,类型:PIL.PngImagePlugin.PngImageFile
			
			imgW= img.size[0]# 图像宽度
			imgH= img.size[1]# 图像长度if imgW>1920:# 图像宽度不超过1920
				zoom=1920/imgWelse:
				zoom=1
			imgResize= img.resize((int(imgW*zoom),int(imgH*zoom)), Image.Resampling.LANCZOS)# 调整后的图像
			
			imgIO= BytesIO()# 创建文件对象,类型:io.BytesIO
			imgResize.save(imgIO,'JPEG')# 以JPEG格式存储,减少数据大小
			
			imgIOZ= BytesIO()# 创建文件对象,类型:io.BytesIO
			imgIOZ.write(gzip.compress(imgIO.getvalue()))# 压缩原图并存入文件对象
			
			imgBytes= imgIOZ.getvalue()# 图像的字节流,类型:bytesprint(len(imgBytes))# 显示字节流长度
			
			imgSize=len(imgBytes)# 图像大小(字节流长度),类型:int
			head= struct.pack('l', imgSize)# 构造文件头信息,内容是图像大小(字节流长度),类型:bytes
			s.send(head)# 发送文件头
		
			imgIOZ.seek(0,0)# 从开头读取图片whileTrue:
				imgBuf= imgIOZ.read(self.bufSize)# self.bufSize大小的图片,类型:bytesifnot imgBuf:# 传输完成退出循环break
				s.send(imgBuf)# 发送self.bufSize大小的图片defClient(self):whileTrue:# 死循环加上try语句可以不用考虑先运行服务器端try:# 连接不上重试
				s= socket.socket()
				s.connect(('192.168.3.126',9099))# 自定义服务器IP和端口except Exceptionas e:print('Connection error')print(e)
				s.close()continuetry:# 传输数据发生错误重试
				self.Data(s)# 处理数据并传输except Exceptionas e:print('Data error')print(e)finally:
				s.close()if __name__=='__main__':
	CLIENT().Client()

服务器端

# -*- coding: utf-8 -*-import socketserver, struct, gzip, timefrom PILimport ImageFile, Imagefrom ioimport BytesIOdefSave(imgBytes):
	imgIO= BytesIO(imgBytes)
	img= Image.open(imgIO)
	img= img.convert('YCbCr')# 转换成YCbCr格式
	img.save('.\screenshot\{:.2f}.jpeg'.format(time.time()))classDATA(socketserver.BaseRequestHandler):defhandle(self):
		ImageFile.LOAD_TRUNCATED_IMAGES=True

		s= self.requestwhileTrue:
			headSize= struct.calcsize('l')# 计算文件头长度
			head= s.recv(headSize)# 接收文件头if head:
				imgSize= struct.unpack('l', head)[0]# 获取图像长度,类型:int
				recvSize=0# 接收到的数据长度
				imgBytesZ=b''# 接收到的数据whileTrue:if imgSize- recvSize>0:# 不断接收数据直至没有数据
						imgBuf= s.recv(SERVER().bufSize)
						recvSize+=len(imgBuf)else:break

					imgBytesZ+= imgBuf

				imgBytes= gzip.decompress(imgBytesZ)# 解压数据
				Save(imgBytes)# 保存图像classSERVER():def__init__(self):
		self.bufSize=10240# 每一次接受的字节流长度defServer(self):
		server= socketserver.ThreadingTCPServer(('0.0.0.0',9099), DATA)# 自定义端口
		server.serve_forever()if __name__=="__main__":
	SERVER().Server()
  • 作者:greatmasonw
  • 原文链接:https://blog.csdn.net/aloe_gel/article/details/124439947
    更新时间:2022-08-23 12:25:47