Django PIL : IOError Ne peut pas identifier le fichier image
Je suis en train d'apprendre Python et Django.
Une image est fournie par l'utilisateur à l'aide de formulaires.ImageField(). Puis-je le traiter afin de créer deux tailles d'images.
Lorsque je soumets le formulaire, Django renvoie l'erreur suivante:
IOError at /add_event/
cannot identify image file
J'appelle la fonction de redimensionnement:
def create_event(owner_id, name, image):
image_thumb = image_resizer(image, name, '_t', 'events', 180, 120)
image_medium = image_resizer(image, name, '_m', 'events', 300, 200)
Je reçois en cas d'erreur lors de l'image_resizer est appelé pour la deuxième fois:
def image_resizer(image, name, size, app_name, length, height):
im = Image.open(image)
if im.mode != "RGB":
im = im.convert("RGB")
im = create_thumb(im, length, height)
posit = str(MEDIA_ROOT)+'/'+app_name+'/'
image_2 = im
image_name = name + size +'.jpg'
imageurl = posit + image_name
image_2.save(imageurl,'JPEG',quality=80)
url_image='/'+app_name+'/'+image_name
return url_image
Versions:
Django 1.3.1
Python 2.7.1
PIL 1.1.7
J'essaie de trouver le problème, mais je ne sais pas quoi faire. Je vous remercie à l'avancée de!
MODIFIER
J'ai résolu la réécriture de la fonction; maintenant, il crée les différentes images dans le lot:
J'appelle la fonction de redimensionnement:
url_array = image_resizer.resize_batch(image, image_name, [[180,120,'_t'], [300,200,'_m']], '/events/')
donc:
image_thumb = url_array[0]
image_medium = url_array[1]
et la fonction de redimensionnement:
def resize_batch(image, name, size_array, position):
im = Image.open(image)
if im.mode != "RGB":
im = im.convert("RGB")
url_array = []
for size in size_array:
new_im = create_thumb(im, size[0], size[1])
posit = str(MEDIA_ROOT) + position
image_name = name + size[2] +'.jpg'
imageurl = posit + image_name
new_im.save(imageurl,'JPEG',quality=90)
new_url_array = position + image_name
url_array.append(new_url_array)
return url_array
Merci à tous!
Image.open()
? Ce chemin d'accès est indiqué là? Est-il vraiment un fichier image valide à ce chemin?Oui, il est soulevé sur
Image.open()
, il est de type <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
. Maintenant, je vais essayer de le résoudre à l'aide de la solution proposée par @gareth-rees.Si vous passez de l'Image.open() d'un objet fichier, ce fichier objet doit avoir été précédemment ouvert en mode binaire. C'est probablement le problème, mais il est impossible de déterminer à partir de votre code.
OriginalL'auteur enri | 2012-03-30
Vous devez vous connecter pour publier un commentaire.
Comme ilvar demande dans les commentaires, quel type d'objet est
image
? Je vais supposer pour les besoins de cette réponse que c'est lafile
propriété de DjangoImageField
qui vient à partir d'un fichier téléchargé par un utilisateur distant.Après le chargement d'un fichier, l'objet que vous obtenez dans le
ImageField.file
propriété est unTemporaryUploadedFile
objet qui pourrait représenter un fichier sur disque ou en mémoire, selon la taille de l'upload a été. Cet objet se comporte un peu comme un normal Python fichier objet, donc après vous avoir lu une fois (pour faire la première miniature de), vous avez atteint la fin du fichier, de sorte que lorsque vous essayez de lire à nouveau (pour faire la deuxième vignette), il n'y a rien, d'où leIOError
. Pour faire un deuxième vignette, vous devez chercher de revenir au début du fichier. Ainsi, vous pouvez ajouter la lignele début de votre
image_resizer
fonction.Mais c'est inutile! Vous avez ce problème, parce que vous demandez au Python Imaging Library à la re-lecture de l'image pour chaque nouvelle vignette que vous souhaitez créer. C'est une perte de temps: mieux vaut lire l'image, juste une fois, puis créer toutes les vignettes que vous voulez.
<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
. Je comprends maintenant leIOError
et je vais réécrire mon code pour lire l'image qu'une seule fois!OriginalL'auteur Gareth Rees
Je suppose que c'est un
TemporaryUploadedFile
... trouver ce type(image).Je ne suis pas sûr à 100% du code ci-dessus ... vient de 2 classes que j'ai eu pour la manipulation d'images ... mais lui donner un essai.
Si est un
InMemoryUploadedFile
votre code devrait fonctionner!Cela ne fonctionne pas. StringIO n'est pas un objet de fichier valide.
OriginalL'auteur StefanNch