Image aus einem Stream auslesen

Alle Fragen zur Netzwerkkommunikation
Antworten
UnixX
Beiträge: 7
Registriert: Do 12. Okt 2017, 18:07

Image aus einem Stream auslesen

Beitrag von UnixX »

Hallo Leute!

Ich habe da ein kleines Problem an dem ich schon länger sitze.
Und zwar geht es darum eine Image aus einem Stream zu lesen der von einem anderen Rechner kommt.

Der Stream wird von einem Python Code erzeugt (zu Anschauung einmal der Code)

Code: Alles auswählen

#!/usr/bin/python
 
import io
import socket
import struct
import time
import picamera
 
# Connect a client socket to my_server:8000 (change my_server to the
# hostname of your server)
client_socket = socket.socket()
client_socket.connect(('192.168.1.111', 8000))
 
# Make a file-like object out of the connection
connection = client_socket.makefile('wb')
try:
    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        # Start a preview and let the camera warm up for 2 seconds
        camera.start_preview()
        time.sleep(2)
 
        # Note the start time and construct a stream to hold image data
        # temporarily (we could write it directly to connection but in this
        # case we want to find out the size of each capture first to keep
        # our protocol simple)
        start = time.time()
        stream = io.BytesIO()
        for foo in camera.capture_continuous(stream, 'jpeg'):
            # Write the length of the capture to the stream and flush to
            # ensure it actually gets sent
            connection.write(struct.pack('<L', stream.tell()))
            connection.flush()
            # Rewind the stream and send the image data over the wire
            stream.seek(0)
            connection.write(stream.read())
            # If we've been capturing for more than 30 seconds, quit
            if time.time() - start > 30:
                break
            # Reset the stream for the next capture
            stream.seek(0)
            stream.truncate()
    # Write a length of zero to the stream to signal we'
re done
    connection.write(struct.pack('<L', 0))
finally:
    connection.close()
    client_socket.close()


Und empfangen von diesem Code

Code: Alles auswählen

#!/usr/bin/python
 
import time
import threading
import random
import Queue
from PIL import Image, ImageTk
import Tkinter as tk
import socket
import struct
import io
import tkMessageBox
 
class GuiPart:
 
    def __init__(self, master, queue, endCommand):
        self.queue = queue
        self.endCommand = endCommand
 
        self.root=master
        self.root.title('My Pictures')
 
        imageFile = "ubuntu640x480.jpg"
        self.image1 = ImageTk.PhotoImage(Image.open(imageFile))
        w = 640
        h = 480
        x = 0
        y = 0
        self.root.geometry("%dx%d+%d+%d" % (w, h, x, y))
 
        self.panel1 = tk.Label(self.root, image=self.image1)
 
        self.panel1.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
        self.panel1.configure(image=self.image1)
 
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
 
    def on_closing(self):
        if tkMessageBox.askokcancel("Quit", "Do you want to quit?"):
            self.endCommand()
            self.root.destroy()
 
    def processIncoming(self):
        """Handle all messages currently in the queue, if any."""
        while self.queue.qsize(  ):
            try:
                self.update_image(self.queue.get(0))
            except Queue.Empty:
                # just on general principles, although we don't
                # expect this branch to be taken in this case
                pass
    def update_image(self, newImage):
        self.image1=newImage
        self.panel1.configure(image=self.image1)
 
class ThreadedClient:
    def __init__(self, master):
        self.master = master
        self.queue = Queue.Queue(  )
        self.gui = GuiPart(master, self.queue, self.endApplication)
 
        # Set up the thread to do asynchronous I/O
        # More threads can also be created and used, if necessary
        self.running = 1
        self.thread1 = threading.Thread(target=self.workerThread1)
        self.thread1.start(  )
 
        # Start the periodic call in the GUI to check if the queue contains
        # anything
        self.periodicCall(  )
 
    def periodicCall(self):
        """
        Check every 200 ms if there is something new in the queue.
        """
        self.gui.processIncoming(  )
        if not self.running:
            # This is the brutal stop of the system. You may want to do
            # some cleanup before actually shutting it down.
            import sys
            sys.exit(1)
        self.master.after(200, self.periodicCall)
 
    def workerThread1(self):
        #set up server
        # Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means
        # all interfaces)
        self.server_socket = socket.socket()
        self.server_socket.bind(('
0.0.0.0', 8000))
        self.server_socket.listen(0)
 
        # Accept a single connection and make a file-like object out of it
        self.connection = self.server_socket.accept()[0].makefile('
rb')
 
        try:
            while self.running:
                # Read the length of the image as a 32-bit unsigned int. If the
                # length is zero, quit the loop
                image_len = struct.unpack('
<L', self.connection.read(struct.calcsize('<L')))[0]
                if not image_len:
                    break
                # Construct a stream to hold the image data and read the image
                # data from the connection
                image_stream = io.BytesIO()
                image_stream.write(self.connection.read(image_len))
 
 
                image_stream.seek(0)
 
                newPhotoImage=ImageTk.PhotoImage(Image.open(image_stream))
 
                #self.image.save('
sbild.jpg')
                self.queue.put(newPhotoImage)
        finally:
            self.connection.close()
            self.server_socket.close()
 
 
 
    def endApplication(self):
        self.master.destroy()
        self.running = 0
 
 
 
root = tk.Tk(  )
 
client = ThreadedClient(root)
root.mainloop(  )


Nun möchte ich das empfangen des Streams mit Pascal realisieren. Um das Programm netzwerkfähig zu machen verwende ich lnet.
Nun habe ich alles mögliche ausprobiert und vieles darüber gelesen wie man Images aus Streams laden kann usw. Leider bekomme ich es nicht hin am Socket den Stream abzugreifen und die Image auszulesen.

Code: Alles auswählen

procedure TForm1.S_LTCPReceive(aSocket: TLSocket);
var
bdata:byte;
begin
  aSocket.Get (bdata,sizeof(bdata));       //<====  hier habe ich versucht den Stream als Byte auszulesen. Und das ist mein Problem! Wie bekomme ich die Daten in einen Stream???
 
// Dann müsste hier ein Code folgen, der ein so wie ich es verstanden habe ein CreateBlobStream(FieldByName('<L'), bmread) beinhaltet um den gesendeten Stream zu entpacken
 
end


Vielleicht hat der eine, oder der Andere von euch eine Idee oder ein Tipp für mich.

Vielen Dank!

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Image aus einem Stream auslesen

Beitrag von Socke »

Du kannst die Daten erst in einen TMemoryStream schreiben, dann die aktuelle Position des Streams auf 0 setzen und das Bild daraus auslesen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten