客户端截屏传给服务器端
客户端
# -*- coding: utf-8 -*-
import socket, struct, pyscreenshot, gzip
from PIL import Image
from io import BytesIO
class CLIENT():
def __init__(self):
self.bufSize = 10240 # 每一次传输的字节流长度
def Data(self, s):
while True:
img = pyscreenshot.grab() # 截取屏幕图像,类型:PIL.PngImagePlugin.PngImageFile
imgW = img.size[0] # 图像宽度
imgH = img.size[1] # 图像长度
if imgW > 1920: # 图像宽度不超过1920
zoom = 1920/imgW
else:
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() # 图像的字节流,类型:bytes
print(len(imgBytes)) # 显示字节流长度
imgSize = len(imgBytes) # 图像大小(字节流长度),类型:int
head = struct.pack('l', imgSize) # 构造文件头信息,内容是图像大小(字节流长度),类型:bytes
s.send(head) # 发送文件头
imgIOZ.seek(0,0) # 从开头读取图片
while True:
imgBuf = imgIOZ.read(self.bufSize) # self.bufSize大小的图片,类型:bytes
if not imgBuf: # 传输完成退出循环
break
s.send(imgBuf) # 发送self.bufSize大小的图片
def Client(self):
while True: # 死循环加上try语句可以不用考虑先运行服务器端
try: # 连接不上重试
s = socket.socket()
s.connect(('192.168.3.126', 9099)) # 自定义服务器IP和端口
except Exception as e:
print('Connection error')
print(e)
s.close()
continue
try: # 传输数据发生错误重试
self.Data(s) # 处理数据并传输
except Exception as e:
print('Data error')
print(e)
finally:
s.close()
if __name__ == '__main__':
CLIENT().Client()
服务器端
# -*- coding: utf-8 -*-
import socketserver, struct, gzip, time
from PIL import ImageFile, Image
from io import BytesIO
def Save(imgBytes):
imgIO = BytesIO(imgBytes)
img = Image.open(imgIO)
img = img.convert('YCbCr') # 转换成YCbCr格式
img.save('.\screenshot\{:.2f}.jpeg'.format(time.time()))
class DATA(socketserver.BaseRequestHandler):
def handle(self):
ImageFile.LOAD_TRUNCATED_IMAGES = True
s = self.request
while True:
headSize = struct.calcsize('l') # 计算文件头长度
head = s.recv(headSize) # 接收文件头
if head:
imgSize = struct.unpack('l', head)[0] # 获取图像长度,类型:int
recvSize = 0 # 接收到的数据长度
imgBytesZ = b'' # 接收到的数据
while True:
if imgSize - recvSize > 0: # 不断接收数据直至没有数据
imgBuf = s.recv(SERVER().bufSize)
recvSize += len(imgBuf)
else:
break
imgBytesZ += imgBuf
imgBytes = gzip.decompress(imgBytesZ) # 解压数据
Save(imgBytes) # 保存图像
class SERVER():
def __init__(self):
self.bufSize = 10240 # 每一次接受的字节流长度
def Server(self):
server = socketserver.ThreadingTCPServer(('0.0.0.0', 9099), DATA) # 自定义端口
server.serve_forever()
if __name__ == "__main__":
SERVER().Server()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)