70
votes

I have this image with size 128 x 128 pixels and RGBA stored as byte values in my memory. But

from PIL import Image

image_data = ... # byte values of the image
image = Image.frombytes('RGBA', (128,128), image_data)
image.show()

throws the exception

ValueError: not enough image data

Why? What am I doing wrong?

2
the raw data in a .png file has headers and compression and stuff, so I don't think you can feed it into frombytes and get a coherent result.Kevin
How do I get rid of this?Michael Dorner
I guess you could open the image with Image.open("homer.jpg"), and then call tobytes on it to get a buffer suitable for passing to frombytes... But there's not much point in doing image = Image.frombytes(Image.open("homer.jpg").tobytes()) when you can just do image = Image.open("homer.jpg"). I'm assuming your actual use case is more complicated and you can't do the latter for some reason.Kevin
So your actual question is "how do I read data from a socket?"?Kevin
No, this works already. But instead of socket -> store image to file -> load from this file -> done I want socket -> done . I tried to make the question a little bit more clear!Michael Dorner

2 Answers

240
votes

The documentation for Image.open says that it can accept a file-like object, so you should be able to pass in a io.BytesIO object created from the bytes object containing the encoded image:

from PIL import Image
import io

image_data = ... # byte values of the image
image = Image.open(io.BytesIO(image_data))
image.show()
21
votes

You can try this:

image = Image.frombytes('RGBA', (128,128), image_data, 'raw')
Source Code:
def frombytes(mode, size, data, decoder_name="raw", *args):
    param mode: The image mode.
    param size: The image size.
    param data: A byte buffer containing raw data for the given mode.
    param decoder_name: What decoder to use.