简体   繁体   中英

How to swap a string between two running python programs?

I want to swap an image generated by a python program to another running python program by using a string.

(I have to use a string because in the real application the string is coming from a C-program and not a python program but that doesn't matter)

So with one program I have to read what the other printed in the console.

But like I did it now, it don't work, the image is not correctly transmitted when I run the two programs in parallel, the image is just gray, so the reader string is not similar to the printed string.

Where is my mistake here?

Sender Program:

import time
from PIL import Image
import sys

image = Image.open("t.png")

while True:
    print(image.tobytes())
    time.sleep(5)

Receiver Program:

import os
import sys
from PIL import Image
from subprocess import Popen, PIPE, STDOUT

script_path = os.path.join('lsend.py')

p = Popen([sys.executable, '-u', script_path],
          stdout=PIPE, stderr=STDOUT, bufsize=1)

while True:
    string = p.stdout.readline()
    print("image received !!!")
    print(string[0:10])
    try:
        image = Image.frombytes('RGBA',(90, 36),string,"raw")
        image.show()
    except:
        print("fail")

My Image:

my test image

Thanks for your answers!

I think there are two issues with your code:

  • there is no message boundary - the sender just sends a continuous stream of bytes and the receiver has no idea where one image ends and the next begins, and

  • Image.tobytes() seems to want to pair up with Image.frombuffer() rather than Image.frombytes() - no idea why!

So, I made your sender just send a single image and your receiver just receive a single image. I guess you would want to put some protocol on top that says how many bytes are coming, then the receiver would stop after receiving one image and start expecting a new byte count.

Here's lsend.py :

#!/usr/bin/env python3

import sys
from PIL import Image

image = Image.open('lora.png').convert('RGB')
sys.stdout.buffer.write(image.tobytes())

And here is receiver.py :

#!/usr/bin/env python3

import os
import sys
from PIL import Image
from subprocess import Popen, PIPE, STDOUT, DEVNULL

process = Popen(['./lsend.py'], stdout=PIPE, stderr=DEVNULL)
stdout, _ = process.communicate()

try:
   image = Image.frombuffer('RGB',(90,36),stdout)
   image.show()
except:
   print("fail")

If the end result is to transmit video, I would recommend using sockets.

Python should provide everything you need in the socket library

This should give a general idea of how sending data over a socket works:

sender.py

import socket

# Host the socket on localhost for this example.
# This could send over a network too though.
host = "0.0.0.0"
port = 8000

# Initialize the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))

# The number of connections to listen for.
sock.listen(5)
print("Server listening.")

while True:

    try:
        # Accept an incoming connection from the client.
        client, addr = sock.accept()
        print("Accepted connection from client.")

        # Wait until the client sends data.
        data = client.recv(1024)
        print(data)

        # Send some data back to the client.
        s = "Hello client"
        client.send(s.encode())

        client.close()

    except KeyboardInterrupt:
        break

Connecting to the socket is similar to hosting it. Instead of calling socket.bind , just call the socket.connect , and remove the socket.listen .

receiver.py

import socket

# The host and port the socket is hosted on.
host = "0.0.0.0"
port = 8000

# Create the socket and connect to the server.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))

# Send the server some data.
s = "Hello server"
sock.send(s.encode())

# And receive some back.
data = sock.recv(1024)
print(data)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM