PIL cannot identify image file for io.BytesIO object
Asked Answered
F

8

57

I am using the Pillow fork of PIL and keep receiving the error

OSError: cannot identify image file <_io.BytesIO object at 0x103a47468>

when trying to open an image. I am using virtualenv with python 3.4 and no installation of PIL.

I have tried to find a solution to this based on others encountering the same problem, however, those solutions did not work for me. Here is my code:

from PIL import Image
import io

# This portion is part of my test code
byteImg = Image.open("some/location/to/a/file/in/my/directories.png").tobytes()

# Non test code
dataBytesIO = io.BytesIO(byteImg)
Image.open(dataBytesIO) # <- Error here

The image exists in the initial opening of the file and it gets converted to bytes. This appears to work for almost everyone else but I can't figure out why it fails for me.

EDIT:

dataBytesIO.seek(0)

does not work as a solution (tried it) since I'm not saving the image via a stream, I'm just instantiating the BytesIO with data, therefore (if I'm thinking of this correctly) seek should already be at 0.

Forgetmenot answered 26/6, 2015 at 15:49 Comment(4)
possible duplicate of PIL open() method not working with BytesIOReverence
I'd recommend moving the solution from the post to its own answer. Just for formatting sakeBarbate
@FracturedRetina I agree. Please move the answer to a separe post, so that the community can vote on it and so that you can earn reputation, Elan M.Ragsdale
It happened to me when accidentally loading a PDF instead of PNG.Oxyacetylene
D
50

(This solution is from the author himself. I have just moved it here.)

SOLUTION:

# This portion is part of my test code
byteImgIO = io.BytesIO()
byteImg = Image.open("some/location/to/a/file/in/my/directories.png")
byteImg.save(byteImgIO, "PNG")
byteImgIO.seek(0)
byteImg = byteImgIO.read()


# Non test code
dataBytesIO = io.BytesIO(byteImg)
Image.open(dataBytesIO)

The problem was with the way that Image.tobytes()was returning the byte object. It appeared to be invalid data and the 'encoding' couldn't be anything other than raw which still appeared to output wrong data since almost every byte appeared in the format \xff\. However, saving the bytes via BytesIO and using the .read() function to read the entire image gave the correct bytes that when needed later could actually be used.

Deathday answered 24/9, 2017 at 19:53 Comment(1)
I am seeing this issue on colab with simple image loading from a url. However, all this code seems to do is convert back and forth between io.BytesIO() and bytes and doesn't seem to accomplish anything. How this fixes anything and the number of upvotes is a mystery.Baud
R
3

On some cases the same error happens when you are dealing with a Raw Image file such CR2. Example: http://www.rawsamples.ch/raws/canon/g10/RAW_CANON_G10.CR2

when you try to run:

byteImg = Image.open("RAW_CANON_G10.CR2")

You will get this error:

OSError: cannot identify image file 'RAW_CANON_G10.CR2'

So you need to convert the image using rawkit first, here is an example how to do it:

from io import BytesIO
from PIL import Image, ImageFile
import numpy
from rawkit import raw
def convert_cr2_to_jpg(raw_image):
    raw_image_process = raw.Raw(raw_image)
    buffered_image = numpy.array(raw_image_process.to_buffer())
    if raw_image_process.metadata.orientation == 0:
        jpg_image_height = raw_image_process.metadata.height
        jpg_image_width = raw_image_process.metadata.width
    else:
        jpg_image_height = raw_image_process.metadata.width
        jpg_image_width = raw_image_process.metadata.height
    jpg_image = Image.frombytes('RGB', (jpg_image_width, jpg_image_height), buffered_image)
    return jpg_image

byteImg = convert_cr2_to_jpg("RAW_CANON_G10.CR2")

Code credit if for mateusz-michalik on GitHub (https://github.com/mateusz-michalik/cr2-to-jpg/blob/master/cr2-to-jpg.py)

Rumor answered 15/8, 2018 at 0:14 Comment(0)
E
3

image = Image.open(io.BytesIO(decoded)) # File "C:\Users\14088\anaconda3\envs\tensorflow\lib\site-packages\PIL\Image.py", line 2968, in open # "cannot identify image file %r" % (filename if filename else fp) # PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x000002B733BB11C8>

=== I fixed as worked: message = request.get_json(force=True)

encoded = message['image']
# https://mcmap.net/q/301544/-decoding-base64-from-post-to-use-in-pil
#image_data = re.sub('^data:image/.+;base64,', '', message['image'])
image_data = re.sub('^data:image/.+;base64,', '', encoded)
# Remove extra "data:image/...'base64" is Very important
# If "data:image/...'base64" is not remove, the following line generate an error message: 
# File "C:\Work\SVU\950_SVU_DL_TF\sec07_TF_Flask06_09\32_KerasFlask06_VisualD3\32_predict_app.py", line 69, in predict
# image = Image.open(io.BytesIO(decoded))
# File "C:\Users\14088\anaconda3\envs\tensorflow\lib\site-packages\PIL\Image.py", line 2968, in open
# "cannot identify image file %r" % (filename if filename else fp)
# PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x000002B733BB11C8>
# image = Image.open(BytesIO(base64.b64decode(image_data)))
decoded = base64.b64decode(image_data)
image = Image.open(io.BytesIO(decoded))
# return json.dumps({'result': 'success'}), 200, {'ContentType': 'application/json'}
#print('@app.route => image:')
#print()
processed_image = preprocess_image(image, target_size=(224, 224))

prediction = model.predict(processed_image).tolist()
#print('prediction:', prediction)
response = {
    'prediction': {
        'dog': prediction[0][0],
        'cat': prediction[0][1]
    }
}
print('response:', response)
return jsonify(response)
Elementary answered 9/5, 2021 at 2:26 Comment(0)
M
2

While reading Dicom files the problem might be caused due to Dicom compression. Make sure both gdcm and pydicom are installed.

GDCM is usually the one that's more difficult to install. The latest way to easily install the same is

conda install -U conda-forge gdcm
Maeda answered 29/4, 2019 at 17:55 Comment(0)
V
0

The image file itself might be corrupted. So if you were to process a considerable amount of image files, then simply enclose the line that processes each image file with a try catch statement.

Vada answered 2/12, 2021 at 19:43 Comment(0)
B
0

When dealing with url, this error can arise from a wrong extension of the downloaded file or just a corrupted file.

So to avoid that use a try/except bloc so you app doesn't crash and will continue its job.

In the except part, you can retrieve the file in question for analysis:

A snippet here:

for url in urls:
    with closing(urllib.request.urlopen(url)) as f:
        try:
            img = Image(f, 30*mm, 30*mm)
            d_img.append(img) 

         except Exception as e:
                    print(url) #here you get the file causing the exception
                    print(e)

Here a related answer

Biodegradable answered 26/7, 2022 at 5:50 Comment(0)
S
0

You can try this way, this is working for me to open image link :

from PIL import Image
import urllib.request
urllib.request.urlretrieve('https://blog.finxter.com/wp-content/uploads/2022/04/greenland_01a.jpg',"C:\\Users\luxman\Desktop\Devon5G ROW India test bat\gfg.jpg")
img = Image.open("C:\\Users\luxman\Desktop\Devon5G ROW India test bat\gfg.jpg")
img.show()
Sherlynsherm answered 1/4, 2023 at 8:3 Comment(0)
M
-1

For me, the problem was that PIL.Image was not properly initialized.

I imported another package that set Image._initialized = 2 manually, thus preventing PIL.Image to load necessary data.

See here for more info.

I resolved the issue by setting Image._initialized to 1 again before calling Image.open():

Image._initialized = 1
Image.open(dataBytesIO)
Memorialist answered 22/5, 2024 at 12:38 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.