Cristi Jiru
Cristi Jiru

Reputation: 55

How can I display an image in Python that's represented as an array of bytes without writing it to a file?

I have successfully sent an image through a socket and, on the receiving end, I have the exact same raw bytes that the image file that was sent had. This means that if I binary write those bytes to a file, I'll obtain the same file as the one that was sent. I have tried showing the image from Python without saving it first, but I'm having trouble doing so. If I understand correctly, matplotlib.imread() requires the path to a file and then decodes that file into several matrices. Doing something like this works fine:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# data is the image data that was received from the socket

file = open("d:\\image.png", 'wb')
file.write(data)
file.close()

img = mpimg.imread("d:\\image.png")
plt.imshow(img)
plt.show()

Obviously I should use a temporary file for that, but I wrote that just for the sake of the example. Is there any way to call the imshow() and show() methods without having called imread() beforehand, provided I already have those bytes?

Upvotes: 4

Views: 11970

Answers (1)

Marc Sances
Marc Sances

Reputation: 2614

If it's OK for you to read from the socket directly, you can convert the socket to a file object using makefile(), then provide the socket to imread as you would with a regular file. Remember to set the codec when reading:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# don't read from your socket, instead, call this where you would call read
fp = your_socket.makefile()

with fp:
    img = mpimg.imread(fp, format='jpeg')
plt.imshow(img)
plt.show()

I've searched and couldn't find a way to directly decode images from bytes in matplotlib. If it is not OK to use the above solution because you have already the bytes array, then use BytesIO to create a temporary buffer:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import io

fp = io.BytesIO(data)

with fp:
    img = mpimg.imread(fp, format='jpeg')
plt.imshow(img)
plt.show()

Upvotes: 11

Related Questions