PIL 无法识别 io.BytesIO 对象的图像文件

问题描述 投票:0回答:7

我正在使用 PIL 的 Pillow fork 并不断收到错误消息

OSError:无法识别图像文件<_io.BytesIO object at 0x103a47468>

尝试打开图像时。我在 python 3.4 中使用 virtualenv,没有安装 PIL。

我试图根据其他遇到同样问题的人找到解决方案,但是,这些解决方案对我不起作用。这是我的代码:

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

图像存在于文件的初始打开中,并被转换为字节。这似乎对几乎所有人都有效,但我不明白为什么它对我失败了。

编辑:

dataBytesIO.seek(0)

不能作为解决方案(试过),因为我没有通过流保存图像,我只是用数据实例化 BytesIO,因此(如果我没有想错的话)seek 应该已经是 0 .

python python-imaging-library bytesio
7个回答
42
投票

(此解决方案来自作者本人,我只是将其移至此处。)

解决方案:

# 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)

问题在于

Image.tobytes()
返回字节对象的方式。它似乎是无效数据,“编码”只能是原始数据,它似乎仍然输出错误数据,因为几乎每个字节都以
\xff\
格式出现。然而,通过 BytesIO 保存字节并使用
.read()
函数读取整个图像给出了正确的字节,以后需要时可以实际使用。


2
投票

在某些情况下,当您处理 CR2 等原始图像文件时,会发生相同的错误。示例:http://www.rawsamples.ch/raws/canon/g10/RAW_CANON_G10.CR2

当你尝试跑步时:

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

你会得到这个错误:

OSError: cannot identify image file 'RAW_CANON_G10.CR2'

所以你需要先使用rawkit转换图像,这里是一个如何做的例子:

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")

GitHub 上 mateusz-michalik 的代码信用(https://github.com/mateusz-michalik/cr2-to-jpg/blob/master/cr2-to-jpg.py


2
投票

读取 Dicom 文件时,问题可能是由于 Dicom 压缩引起的。 确保安装了 gdcm 和 pydicom。

GDCM 通常是更难安装的那个。轻松安装相同的最新方法是

conda install -U conda-forge gdcm

2
投票

image = Image.open(io.BytesIO(解码)) # 文件“C:\Users`88 naconda3 nvs ensorflow\lib\site-packages\PIL\Image.py”,第 2968 行,打开 # "无法识别图像文件 %r" % (filename if filename else fp) # PIL.UnidentifiedImageError: 无法识别图像文件<_io.BytesIO object at 0x000002B733BB11C8>

=== 我修复了工作: 消息 = request.get_json(force=True)

encoded = message['image']
# https://stackoverflow.com/questions/26070547/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)

1
投票

在处理 url 时,这个错误可能是由于下载的错误扩展名引起的 文件或只是一个损坏的文件。

所以为了避免使用 try/except bloc,这样你的应用程序就不会崩溃并且会继续它的工作。

except部分,可以检索出问题文件进行分析:

这里有一个片段:

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)

这里有一个相关的答案


0
投票

图像文件本身可能已损坏。因此,如果您要处理大量图像文件,则只需将处理每个图像文件的行用 try catch 语句括起来。


0
投票

你可以试试这个方法,这对我打开图片链接很有效:

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()
© www.soinside.com 2019 - 2024. All rights reserved.