【问题标题】:sending a screenshot using python使用 python 发送屏幕截图
【发布时间】:2019-11-25 18:45:51
【问题描述】:

我正在尝试截取屏幕截图并使用 python 将其发送到另一台计算机。 我尝试过很多不同的方法。不幸的是,我没有找到办法。 非常感谢您的帮助!

服务器:

from PIL import Image
from PIL import ImageGrab
import socket


server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 1111))
server_socket.listen(1)
print('Waiting For Connection...')
(client_socket, client_address) = server_socket.accept()
print('Connected to: ', client_address[0])


img = ImageGrab.grab(bbox=(10, 10, 500, 500))
photo_to_send= img.tobytes()
size = len(photo_to_send)
client_socket.send(bytes(str(size), 'utf-8'))

while size >= 0:
    msg = photo_to_send[:4096]
    client_socket.send(bytes(str(msg), 'utf-8'))
    photo_to_send= photo_to_send[4096:]

客户:

import socket
from PIL import Image


my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_socket.connect(('127.0.0.1', 1111))
print("Connected to the server")

size = int(my_socket.recv(1024).decode('utf-8'))

the_photo = ""
the_photo = the_photo.encode('utf-8')

while size > 0:
    data = my_socket.recv(4096)
    size -= len(data)
    the_photo += data


img_to_save = Image.frombytes("RGB", (490,490), the_photo)
img_to_save .save("screenshot.png")

【问题讨论】:

  • 您想使用哪种交通工具?你有什么问题?
  • 我的问题是客户端没有获得所有字节或者他获得了很多字节。结果,客户得到了一张极其模糊的图片。感谢您的帮助!

标签: python sockets


【解决方案1】:

您可以使用pickle 来序列化您的 Image 对象。 Pickle 只是将 python 对象转换为字节。 pickle.dumps 只是将其编码为字节,pickle.loads 将其解码回来。

希望这会有所帮助!

【讨论】:

  • Maybe dont use pickle messagePack 似乎是更安全的选择
  • 我认为图片泡菜更好
  • 我会尝试学习并使用它。感谢您的帮助!!我真的很感激
【解决方案2】:

问题是您在数据本身之前立即发送长度的文本值。例如,如果图像数据以AAABBB 开头,您将发送

1234AAABBB...

但是如果图片更大,你可能会发送类似的东西

56789AAABBB...

客户端无法判断长度在哪里结束,数据从哪里开始!要解决此问题,您需要发送 固定大小 长度参数。如果你仍然想要文本长度,你可以使用zfill:

client_socket.send(str(size).zfill(16).encode())
...
size = int(my_socket.recv(16).decode())

(选择 16 以使其足够长以适应任何可能的图像尺寸)


这不是很有效;真正的协议通常使用二进制编码:

client_socket.send(struct.pack('>I', size))
...
size, = struct.unpack('>I', my_socket.recv(4))

但这可能比您的应用程序需要的更复杂。

【讨论】:

  • 非常感谢您的帮助!不幸的是,这并没有解决我的问题。我的问题是服务器发送的字节数和客户端获取的字节数有点不同。
【解决方案3】:

问题是我对照片进行了两次编码。 谢谢你的帮助! 我真的很感激!

解决办法如下:

服务器:

from PIL import ImageGrab
import socket


server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 1112))
server_socket.listen(1)
print('Waiting For Connection...')
(client_socket, client_address) = server_socket.accept()
print('Connected to: ', client_address[0])


img = ImageGrab.grab(bbox=(10, 10, 500, 500))
photo_to_send = img.tobytes()

size = len(photo_to_send)
print(size)
print(photo_to_send)
client_socket.send(bytes(str(size), 'utf-8'))

client_socket.send(photo_to_send)

客户:

import socket
from PIL import Image

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_socket.connect(('127.0.0.1', 1112))
print("Connected to the server")

size = int(my_socket.recv(10).decode('utf-8'))
print(size)

the_photo = my_socket.recv(size)

print(the_photo)
img_to_save = Image.frombytes("RGB", (490, 490), the_photo)
img_to_save.save("screenshot.png")

【讨论】:

    【解决方案4】:

    structpickle 让您轻松搞定。

    server.py

    imageBytes = pickle.dumps(image)
    sock.sendall(struct.pack("L", len(imageBytes)) + imageBytes)
    

    client.py

    data = b""
    payload_size = struct.calcsize("L")
    while True:
        data += sock.recv(payload_size)
        packedImageSize = data[:payload_size]
        imageSize = struct.unpack("L", packedImageSize)[0]
        data = data[payload_size:]
        while len(data) < imageSize:
            data += sock.recv(65000)
        frameData = data[:imageSize]
        data = data[imageSize:]
        frame = pickle.loads(frameData)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多