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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31077366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:27:12  来源:igfitidea点击:

PIL cannot identify image file for io.BytesIO object

pythonpillowbytesio

提问by Elan M

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

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

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

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

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

尝试打开图像时。我在 python 3.4 中使用 virtualenv 并且没有安装 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.

不能作为解决方案(尝试过),因为我没有通过流保存图像,我只是用数据实例化 BytesIO,因此(如果我正确地考虑这一点)seek 应该已经为 0。

回答by sdikby

(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.

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

回答by Pablo Arias Mora

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

在某些情况下,当您处理 CR2 等原始图像文件时会发生相同的错误。示例: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:

所以你需要先使用 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")

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

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

回答by SinghG

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

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

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

GDCM 通常是较难安装的一种。轻松安装相同的最新方法是

conda install -U conda-forge gdcm