web-dev-qa-db-fra.com

PIL ne peut pas identifier le fichier image pour l'objet io.BytesIO

J'utilise la fourchette à oreiller de PIL et continue de recevoir l'erreur

OSError: impossible d'identifier le fichier image <objet _io.BytesIO à 0x103a47468>

lorsque vous essayez d'ouvrir une image. J'utilise virtualenv avec python 3.4 et aucune installation de PIL.

J'ai essayé de trouver une solution à cela sur la base d'autres personnes rencontrant le même problème, cependant, ces solutions n'ont pas fonctionné pour moi. Voici mon 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

L'image existe dans l'ouverture initiale du fichier et elle est convertie en octets. Cela semble fonctionner pour presque tout le monde, mais je ne peux pas comprendre pourquoi cela échoue pour moi.

ÉDITER:

dataBytesIO.seek(0)

ne fonctionne pas comme une solution (je l'ai essayé) car je ne sauvegarde pas l'image via un flux, j'instancie juste le BytesIO avec des données, donc (si je pense à cela correctement) la recherche devrait déjà être à 0.

18
Elan M

(Cette solution vient de l'auteur lui-même. Je viens de la déplacer ici.)

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)

Le problème venait de la façon dont Image.tobytes() renvoyait l'objet octet. Il semblait s'agir de données non valides et le "codage" ne pouvait être autre que brut qui semblait toujours produire des données erronées puisque presque chaque octet apparaissait au format \xff\. Cependant, l'enregistrement des octets via BytesIO et l'utilisation de la fonction .read() pour lire l'image entière ont donné les octets corrects qui, en cas de besoin, pourraient être utilisés.

21
sdikby

Lors de la lecture des fichiers Dicom, le problème peut être dû à la compression Dicom. Assurez-vous que gdcm et pydicom sont installés.

GDCM est généralement celui qui est le plus difficile à installer. La dernière façon de l'installer facilement est

conda install -U conda-forge gdcm
1
SinghG

Dans certains cas, la même erreur se produit lorsque vous traitez un fichier d'image brute tel que CR2. Exemple: http://www.rawsamples.ch/raws/Canon/g10/RAW_Canon_G10.CR2

lorsque vous essayez d'exécuter:

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

Vous obtiendrez cette erreur:

OSError: cannot identify image file 'RAW_Canon_G10.CR2'

Vous devez donc d'abord convertir l'image à l'aide de rawkit, voici un exemple pour le faire:

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

Crédit de code si pour mateusz-michalik sur GitHub ( https://github.com/mateusz-michalik/cr2-to-jpg/blob/master/cr2-to-jpg.py )

0
Pablo Arias Mora