Django PIL : IOError Nicht identifizieren kann image-Datei
Ich Lerne Python und Django.
Einem Bild wird durch den Benutzer unter Verwendung von Formen.ImageField(). Dann habe ich, um es zu verarbeiten, um zwei Verschieden große Bilder.
Wenn ich das Formular abschicken, Django gibt die folgende Fehlermeldung zurück:
IOError at /add_event/
cannot identify image file
Rufe ich die resize-Funktion:
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)
Bekomme ich de Fehler beim image_resizer ist aufgerufen, zum zweiten mal:
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
Versionen:
Django 1.3.1
Python 2.7.1
PIL 1.1.7
Ich versuche, das problem zu finden, aber ich weiß nicht, was zu tun ist. Vielen Dank im advanced!
BEARBEITEN
Ich löste das umschreiben der Funktion; jetzt schafft es die verschiedenen Bilder im batch:
Rufe ich die resize-Funktion:
url_array = image_resizer.resize_batch(image, image_name, [[180,120,'_t'], [300,200,'_m']], '/events/')
also:
image_thumb = url_array[0]
image_medium = url_array[1]
und die resize-Funktion:
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
Danke an alle!
- Es ist erhöht auf
Image.open()
? Was Weg ist, vorausgesetzt, es? Gibt es wirklich eine gültige Bild-Datei in diesem Pfad? - Ja, es ist angehoben auf
Image.open()
es ist der Typ<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
. Jetzt bin ich versucht zu lösen mit dem Vorschlag von @gareth-rees. - Wenn Sie pass-Bild.open() ein file-Objekt Datei-Objekt muss zuvor im Binärmodus geöffnet. Das ist wahrscheinlich das problem, aber es ist unmöglich zu bestimmen, dass aus dem code.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als ilvar fragt in den Kommentaren, welche Art von Objekt ist
image
? Ich werde davon ausgehen, dass für die Zwecke dieser Antwort, dass es diefile
Eigenschaft von DjangoImageField
kommt aus eine hochgeladene Datei von einem remote-Benutzer.Nach dem hochladen einer Datei, das Objekt, das Sie erhalten in der
ImageField.file
Eigenschaft ist einTemporaryUploadedFile
Objekt darstellen könnten,eine Datei auf der Festplatte oder im Speicher, je nachdem wie groß der laden war. Dieses Objekt verhält sich ähnlich wie ein normaler Die Python Datei Objekt, so, nachdem Sie einmal gelesen (auf die erste Miniaturansicht), Sie haben erreicht das Ende der Datei, so dass, wenn Sie versuchen, es erneut zu Lesen (um die zweite Miniatur), da ist nichts, daher dieIOError
. Eine zweite Miniatur, die Sie benötigen, um suchen zurück an den Anfang der Datei. So könnte man hinzufügen, die Liniedem Beginn Ihrer
image_resizer
Funktion.Aber das ist überflüssig!!! Sie haben das problem nicht, weil Sie Sie bitten, die Python Imaging Library, um wieder Lesen die Bild für jede neue Miniaturansicht, die Sie erstellen möchten. Dies ist eine Verschwendung von Zeit: besser zu Lesen Sie die image nur einmal erstellen und dann alle thumbnails, die Sie wollen.
<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
. Jetzt verstehe ich dieIOError
und ich werde umschreiben, meinen code zu Lesen, das Bild nur einmal!!!!Ich vermute, dass ist ein
TemporaryUploadedFile
... finde das mit dem Typ(Bild).Bin ich mir nicht 100% sicher, dass der code oben ... kommt aus 2 Klassen, die ich habe für die Bildbearbeitung ... aber versuchen Sie es.
Wenn ein
InMemoryUploadedFile
dein code sollte funktionieren!