0

I am currently receiving frames from a socket in Python and the image type being received is bytes. The image is then saved to a directory. As below:

from socket import *
import cv2

port = 9999
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', port))
s.listen(1)
conn, addr = s.accept()
print("Connected by the ",addr)

with open('/home/Desktop/frame/my_image.png', 'wb') as file:
    while True:
        data = conn.recv(1024*8)
        if not data: break
        file.write(data)


conn.close() 

However, what I want to do actually is instead of having to read the image from the saved directory, I would like to directly convert the bytes to image and display it before having to save and open the image.

Code now fully works:

    from socket import *
import datetime
import cv2
import PIL.Image as Image
from PIL import ImageFile, Image
import io
import base64
import numpy as np
import pickle

date_string = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M")
port = 9999
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', port))
s.listen(1)
conn, addr = s.accept()
img_dir = '/home/Desktop/frames_saved/'
img_format = '.png'
b=bytearray()

print("Connected by the ",addr)

with open(img_dir+date_string+img_format, 'wb') as file:
    while True:
        data = conn.recv(1024*1024*1)
        if not data: break
        file.write(data)
        b += data

conn.close()
ImageFile.LOAD_TRUNCATED_IMAGES = True
image = Image.open(io.BytesIO(b))
image.show()
2
  • You didn't mention if your existing code works or not (when written to a file). Commented Nov 29, 2021 at 7:13
  • The code works perfectly when I am not trying to convert bytes to image, but just save the file while it was received Commented Nov 29, 2021 at 16:23

2 Answers 2

1

A few observations:

  • your code that writes to a file does conn.recv() inside a while loop, receiving up to 8kB at a time and appending what it receives each time to a file. Your code that doesn't work, fails to accumulate anything, it just tries to interpret whatever it gets each time as an image. So you need to accumulate what you receive into something larger and then open it after the end of the loop
  • you can help yourself by debugging, so print the length of the data you receive on each iteration, i.e. len(data)
  • if you are expecting to receive something that PIL can open, print the first 20 bytes or so, i.e. data[:20], and check it starts with the same signature (magic number) as another, normal PNG file on disk - use xxd or if you don't have that, try here. The PNG signature is 89 50 4e 47 0d 0a 1a 0a see here.
Sign up to request clarification or add additional context in comments.

5 Comments

I tried to increase the buffer size to nearly 100mb. I also tried appending the chunks of bytes and reading it outside the connection it gives me the same error
Your code creates a new bytearray every time through the loop. You need to create it before the loop starts and just append inside the loop.
Try printing the length of the bytearray at each iteration and compare it with the size of the image you are sending.
It works now, thanks. As for the image size the largest image I sent has 1.5MB. I tunned it down to 3MB
Excellent - well done and good luck with your project.
0

On the receiving end (your client?) you recv the bytes from the socket. I guess you can use Image.frombytes to directly create an image back from it and show that. Alternatively, write the bytes you got from the socket to a new file (make sure to open it with "wb" binary mode) and Image.open() that file.

2 Comments

I already tried doing: ImageFile.LOAD_TRUNCATED_IMAGES = True image = Image.open(io.BytesIO(data)) image.save(img_dir+date_string+img_format). It gives me this error: " ImageFile.LOAD_TRUNCATED_IMAGES = True image = Image.open(io.BytesIO(data)) image.save(img_dir+date_string+img_format)". Additionally a blank image.
Please don't put code in comments where it is unformatted and difficult to read - click edit under your question instead. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.