2

My function accepts bytes to internaly opens them as a PIL.Image object. The function works as expected when bytes are passed to it. But I would like to write a couple of tests to it. So I need to generate images, turn them into bytes and pass them to my function so that it can turn it again back into an image.

Basically I wanna do something like this:

from PIL import Image
from io import BytesIO

orig = Image.new(mode='RGBA', size=(240, 60))
image_bytes = orig.tobytes()
stream = BytesIO(image_bytes)
new = Image.open(stream)

But what I don't understand is that it is not working and I get this Traceback:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/crane/PycharmProjects/my_project/venv/lib/python3.9/site-packages/PIL/Image.py", line 3030, in open
    raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x104f86950>
Denny Crane
  • 637
  • 6
  • 19

1 Answers1

2

A JPEG or PNG file is a compressed representation of an image, with its dimensions, its colourspace and often other metadata such as the date it was taken, the lens, camera and GPS coordinates. The height, width and details of the compression allow a program to unpack, decompress, understand and show the image.

When you do:

image_bytes = orig.tobytes()

your variable image_bytes gets the top-left pixel, followed by the second pixel and third and so on. It doesn't get the size, colourspace or anything else except the pixels.

You can see this if you create a single pixel red image:

im = Image.new('RGB', (1,1), 'red')

print(im.tobytes())

Results in just 3 RGB bytes, no header.

 b'\xff\x00\x00'

And that's what the error message is telling you - Image.open() can't identify the type or size of the image - because it isn't in your variable.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • 1
    This is a great explanation but it is not an answer. I have a different but similar requirement. So is there a way to go to bytes that preserves the size, colorspace etc? Similar to how Path('image.jpeg').read_bytes() works? – Steve Feb 01 '23 at 01:41
  • https://stackoverflow.com/questions/38626692/convert-pil-image-to-bytearray is the answer – Steve Feb 01 '23 at 01:49
  • @Steve It's not clear to me what you start with, nor what you hope to get, so please just go ahead and ask a new question that clarifies your requirements. Questions are free. If you tag it with [tag:PIL] I'll see it tomorrow. – Mark Setchell Feb 01 '23 at 01:49