2010-08-10 23 views
10

Ich habe nach einer Möglichkeit gesucht, ein Bild von einer URL herunterzuladen, einige Bildmanipulationen (Größe ändern) darauf vor, und speichern Sie es dann in a Django ImageField. Mit den zwei tollen Posts (unten verlinkt) konnte ich ein Image auf ein ImageField herunterladen und dort speichern. Allerdings hatte ich einige Probleme, die Datei zu manipulieren, sobald ich sie habe.Python/Django herunterladen Bild von URL, ändern und speichern in ImageField

Insbesondere erfordert das Modellfeld save() - Methode ein File() -Objekt als zweiten Parameter. Also müssen meine Daten irgendwann ein File() Objekt sein. Die unten verlinkten Blogposts zeigen, wie Sie urlib2 verwenden, um eine Bild-URL in einem File() - Objekt zu speichern. Das ist großartig, aber ich möchte auch das Bild mit PIL als Image() -Objekt manipulieren. (oder ImageFile-Objekt).

Meine bevorzugte Vorgehensweise wäre dann, die Bild-URL direkt in ein Image() -Objekt zu laden, die Größenänderung vorzufixieren und in ein File() -Objekt zu konvertieren und dann im Modell zu speichern. Meine Versuche, ein Image() in eine Datei() zu konvertieren, sind jedoch fehlgeschlagen. Wenn möglich, möchte ich die Anzahl der Schreibvorgänge auf dem Datenträger beschränken. Daher möchte ich diese Objekttransformation im Arbeitsspeicher durchführen oder ein NamedTemporaryFile-Objekt (delete = True) verwenden, damit ich mir keine Sorgen machen muss zusätzliche Dateien herumliegen. (Natürlich möchte ich, dass die Datei auf die Festplatte geschrieben wird, sobald sie über das Modell gespeichert wurde).

Mit diesem Ansatz erscheint die Datei beschädigt, wenn ich es als ein Bild anzeigen. Hat jemand einen Ansatz, der eine Datei von einer URL abliest, sie als Bild bearbeiten und dann in einem Django ImageField speichern kann?

Jede Hilfe wird sehr geschätzt.

Programmatically saving image to Django ImageField

Django: add image in an ImageField from image url

-Update 08.11.2010: Ich mit StringIO am Ende haben würde, aber ich war StringIO eine ungewöhnliche Ausnahme wirft, als ich es in einem Django Imagefield zu retten versucht. Insbesondere wird der Stack-Trace einen Namen Fehler zeigte:

"AttribueError exception "StringIO instance has no attribute 'name'" 

Nachdem durch die Django Quelle zu graben, es sieht aus wie dieser Fehler verursacht wurde, wenn das Modell speichern versucht, die Größe Attribut der StringIO „Datei“ zuzugreifen. (Obwohl der obige Fehler auf ein Problem mit dem Namen hinweist, ist die Ursache für diesen Fehler anscheinend das Fehlen einer Größeneigenschaft im StringIO-Image). Sobald ich dem Größenattribut der Bilddatei einen Wert zugewiesen hatte, funktionierte es einwandfrei.

+0

Ich habe auch StringIO verwendet, um das Bild im Speicher zu speichern und dann mit File.open() zu lesen, hatte aber auch einige Probleme damit. –

Antwort

4

In einem Versuch, 2 Vögel mit 1 Stein zu töten. Warum nicht ein (c) StringIO-Objekt anstelle einer NamedTemporaryFile verwenden? Sie müssen es nicht mehr auf der Festplatte speichern und ich weiß, dass so etwas funktioniert (ich benutze einen ähnlichen Code selbst).

+0

Danke WoLpH, ich weiß deine Hilfe zu schätzen. Ich habe deine Lösung versucht, habe aber immer noch Probleme damit. Genauer gesagt, wenn ich save() am Ende aufrufen, bekomme ich die AttributError-Ausnahme "StringIO-Instanz hat kein Attribut 'name'" ------------------ img_temp = StringIO .StringIO(); inImage.save (img_temp, Format = 'PNG'); img_temp.Suche (0); –

+1

@Joe J: Bei Verwendung von 'StringIO' ist das' filename' Argument zwingend erforderlich. Das ist jetzt dein Problem;) – Wolph

+0

Danke nochmal WoLpH. Muss der Dateiname einem Pfad im Dateisystem entsprechen oder kann es sich nur um einen zufälligen Namen für die temporäre Datei handeln? –