53 votes

Comment voulez-vous convertir un PIL `Image` avec un Django "Fichier"?

Je suis en train de prendre un UploadedFile, de les convertir en un PIL Image objet miniature, et le convertir le PIL Image objet que mon pouce,-la création de la fonction retourne en File objet. Comment puis-je faire cela?

104voto

Skitz Points 506

Le moyen de le faire sans avoir à écrire de nouveau sur le système de fichiers, puis de mettre le fichier dans la mémoire via un appel ouvert, est de faire usage de StringIO et Django InMemoryUploadedFile. Voici un échantillon rapide sur comment vous pouvez le faire. Cela suppose que vous avez déjà un thumbnailed image nommée "pouce":

import StringIO

from django.core.files.uploadedfile import InMemoryUploadedFile

# Create a file-like object to write thumb data (thumb data previously created
# using PIL, and stored in variable 'thumb')
thumb_io = StringIO.StringIO()
thumb.save(thumb_io, format='JPEG')

# Create a new Django file-like object to be used in models as ImageField using
# InMemoryUploadedFile.  If you look at the source in Django, a
# SimpleUploadedFile is essentially instantiated similarly to what is shown here
thumb_file = InMemoryUploadedFile(thumb_io, None, 'foo.jpg', 'image/jpeg',
                                  thumb_io.len, None)

# Once you have a Django file-like object, you may assign it to your ImageField
# and save.
...

Laissez-moi savoir si vous avez besoin de plus de précisions. J'ai ce travail dans mon projet, le téléchargement de S3 en utilisant django-entrepôts. Ce qui m'a pris la meilleure partie de la journée pour bien trouver la solution ici.

13voto

Lincoln B Points 1214

J'ai dû le faire en quelques étapes, imagejpeg() en php nécessite un processus similaire. Pour ne pas dire theres aucun moyen de garder les choses en mémoire, mais cette méthode vous donne un fichier de référence à la fois à l'origine de l'image et du pouce (généralement une bonne idée dans le cas où vous devez revenir en arrière et changer votre pouce taille).

  1. enregistrez le fichier
  2. l'ouvrir à partir du système de fichiers avec PIL,
  3. enregistrer dans un répertoire temporaire avec PIL,
  4. ensuite, ouvrez un fichier Django pour que cela fonctionne.

Modèle:

class YourModel(Model):
    img = models.ImageField(upload_to='photos')
    thumb = models.ImageField(upload_to='thumbs')

Utilisation:

#in upload code
uploaded = request.FILES['photo']
from django.core.files.base import ContentFile
file_content = ContentFile(uploaded.read())
new_file = YourModel() 
#1 - get it into the DB and file system so we know the real path
new_file.img.save(str(new_file.id) + '.jpg', file_content)
new_file.save()

from PIL import Image
import os.path

#2, open it from the location django stuck it
thumb = Image.open(new_file.img.path)
thumb.thumbnail(100, 100)

#make tmp filename based on id of the model
filename = str(new_file.id)

#3. save the thumbnail to a temp dir

temp_image = open(os.path.join('/tmp',filename), 'w')
thumb.save(temp_image, 'JPEG')

#4. read the temp file back into a File
from django.core.files import File
thumb_data = open(os.path.join('/tmp',filename), 'r')
thumb_file = File(thumb_data)

new_file.thumb.save(str(new_file.id) + '.jpg', thumb_file)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X