2
votes

I've just started working with PIL and Pygame and I wanted to create a screen-sharing program. In order to take a screenshot I used ImageGrab.grab() and now I want to send it to another computer and open it in Pygame without saving it on any of the computers. This is my server right now:

#region - - - - - - I M P O R T S - - - - - -
import socket
import select
from PIL import ImageGrab
import pickle
#endregion
#region - - - - - - C O N S T A N T S - - - - - -
PORT = 8253
CONCURRENT_USERS = 5
#endregion
#region - - - - - - M E T H O D S - - - - - -
def CaptureScreen():
    img = ImageGrab.grab()
    return img
#endregion
server_socket = socket.socket()
server_socket.bind(('', PORT))
server_socket.listen(CONCURRENT_USERS)
clients_list = []
while True:
    read, write, error = select.select([server_socket] + clients_list, [], [], 0)
    for i in read:
        if i is server_socket:
            client_socket, client_address = server_socket.accept()
            clients_list.append(client_socket)
        for i in clients_list:
            img = CaptureScreen()
            try:
                i.send(pickle.dumps(img))
            except socket.error:
                clients_list.remove(i)
                i.close()

I tried using pickle in order to send the images but I got an error in response. So I am looking for a way to send an image I've captured using ImageGrab through sockets and open it with Pygame on another computer without saving it on any of the computers. Can anyone help me? I'm using Python 2.6 and Windows 7. Thank you in advance!

1

1 Answers

4
votes

You can get the raw image's data with Image.tobytes() and rebuild it from raw data with Image.frombytes(), cf http://pillow.readthedocs.org/en/latest/reference/Image.html#PIL.Image.Image.tobytes and http://pillow.readthedocs.org/en/latest/reference/Image.html#PIL.Image.Image.fromstring

Pickle is a notoriously unsafe protocol FWIW so better to stick with raw data.

Note that these are features from version 2.x of the Pillow fork of PIL. If you are using the original PIL library and cannot update to Pillow, you'll have to either use the Image.tostring() and Image.fromstring() methods, or use the save() and load() functions with a StringIO as file object, as (roughly) documented here. As mentioned by jsbueno, this last solution could save quite some bandwidth...