PIL не может идентифицировать файл изображения для объекта io.BytesIO
Я использую вилку Pillow PIL и продолжаю получать ошибку
OSError: невозможно идентифицировать файл образа < _io.BytesIO объект в 0x103a47468 >
при попытке открыть изображение. Я использую virtualenv с python 3.4 и не устанавливаю 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
Изображение существует в начальном открытии файла и преобразуется в байты. Кажется, что это работает почти для всех, но я не могу понять, почему он терпит неудачу для меня.
EDIT:
dataBytesIO.seek(0)
не работает как решение (попробовал), так как я не сохраняю изображение через поток, я просто создаю BytesIO с данными, поэтому (если я думаю об этом правильно), поиск уже должен быть при 0.
Ответы
Ответ 1
(Это решение принадлежит самому автору. Я только что перевел его сюда.)
РЕШЕНИЕ:
# 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
При чтении файлов Dicom проблема может быть вызвана сжатием Dicom. Убедитесь, что и gdcm, и pydicom установлены.
GDCM обычно более сложен в установке. Последний способ легко установить это
conda install -U conda-forge gdcm
Ответ 3
В некоторых случаях такая же ошибка возникает, когда вы имеете дело с файлом Raw Image, таким как 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")
Код кредита, если для mateusz-michalik на GitHub (https://github.com/mateusz-michalik/cr2-to-jpg/blob/master/cr2-to-jpg.py)
Ответ 4
Это случилось со мной при случайной загрузке PDF вместо PNG.