Как поменять строку между двумя работающими программами на Python? - PullRequest
0 голосов
/ 05 января 2019

Я хочу поменять изображение, созданное программой на Python, на другую работающую программу на языке Python, используя строку.

должен использовать строку , потому что в реальном приложении строка идет из C-программы, а не из программы Python, но это не имеет значения)

Итак, с одной программой мне нужно прочитать, что другая напечатала в консоли.

Но, как я это сделал сейчас, это не работает, изображение передается неправильно, когда я запускаю две программы параллельно, изображение просто серое, поэтому строка считывателя не похожа на напечатанную строку.

Где здесь моя ошибка?

Программа отправителя:

import time
from PIL import Image
import sys

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

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

Программа получателя:

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

Мое изображение:

мое тестовое изображение

Спасибо за ваши ответы!

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Я думаю, что с вашим кодом есть две проблемы:

  • границы сообщения нет - отправитель просто отправляет непрерывный поток байтов, а получатель не знает, где заканчивается одно изображение и начинается следующее, а

  • Image.tobytes(), кажется, хочет соединиться с Image.frombuffer(), а не Image.frombytes() - не знаю почему!

Итак, я заставил вашего отправителя просто отправить одно изображение, а ваш получатель - только одно изображение. Я полагаю, что вы захотите поместить какой-нибудь протокол поверх него, который говорит, сколько байтов поступает, тогда получатель остановится после получения одного изображения и начнет ожидать нового количества байтов.

Вот 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())

А вот и 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")
0 голосов
/ 05 января 2019

Если конечным результатом является передача видео, я бы рекомендовал использовать сокеты.

Python должен предоставить все необходимое в socket библиотеке

Это должно дать общее представление о том, как происходит отправка данных через сокет:

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

Подключение к сокету похоже на его размещение. Вместо вызова socket.bind, просто позвоните socket.connect и удалите 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)
...