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.
I tried converting to bytes and opening the image like this:
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
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'
print("Connected by the ",addr)
with open(img_dir date_string img_format, 'wb') as file:
while True:
data = conn.recv(1024*8)
if not data: break
file.write(data)
ImageFile.LOAD_TRUNCATED_IMAGES = True
image = Image.open(io.BytesIO(data))
image.save(img_dir date_string img_format)
conn.close()
It outputs the following error:
Traceback (most recent call last):
File "script.py", line 32, in <module>
image = Image.open(io.BytesIO(data))
File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2687, in open
% (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0xa6901d80>
CodePudding user response:
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.
CodePudding user response:
A few observations:
- your code that writes to a file does
conn.recv()
inside awhile
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 - usexxd
or if you don't have that, try here. The PNG signature is89 50 4e 47 0d 0a 1a 0a
see here.