客户端截屏传给服务器端
客户端
# -*- 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()