1

J'ai une fonction dans laquelle j'essaye de redimensionner une photo deux fois à partir de request.FILES ['image']. J'utilise aussi l'image.thumbnail() avec l'analyseur. Cela fonctionne bien lorsque je crée une vignette, mais à mon avis, si je répète la même chose à nouveau, il échoue dans l'analyseur via IOError ne peut pas analyser l'image. Je suis très confus. J'ai créé des fichiers StringIO en mémoire au lieu d'utiliser l'objet UploadedFile de Django tel quel et cela fait toujours la même chose. Toute aide est très appréciée.Redimensionner l'image deux fois dans Django en utilisant PIL

Supposons que je voulais faire ce qui suit deux fois (avec deux tailles de thumbnailing différentes) tous sans récupérer l'URL deux fois:

import urllib2 
from PIL import Image, ImageFile, ImageEnhance 

# create Image instance 
file = urllib2.urlopen(r'http://animals.nationalgeographic.com/staticfiles/NGS/Shared/StaticFiles/animals/images/primary/kemps-ridley-sea-turtle.jpg') 
parser = ImageFile.Parser() 
while True: 
    s = file.read(1024) 
    if not s: 
     break 
    parser.feed(s) 
image = parser.close() 

# make thumbnail 
size = (75, 75) 
image.thumbnail(size, Image.ANTIALIAS) 
background = Image.new('RGBA', size, (255, 255, 255, 0)) 
background.paste(
    image, 
    ((size[0] - image.size[0])/2, (size[1] - image.size[1])/2)) 

background.save('copy.jpg') 

Par exemple:

image = parser.close() 
image2 = parser.close() # Obviously this doens't work 
image2 = image # Obviously this doesn't either but you get what I need to do here 
# Do 2 thumbnails with only one original source. 

... autre code omises. ..

image.save('copy.jpg') 
image2.save('copy.jpg') 
+0

Montrez-nous un peu de code! –

Répondre

2

Si cela fonctionne une fois, comme vous le dites, l'image que vous avez récupérée est très bien. Il existe au moins deux manières différentes d'obtenir plusieurs miniatures à partir d'images PIL uniques.

  1. Vous pouvez utiliser la méthode resize de PIL, qui renvoie une copie redimensionnée de l'original. Il vous suffit de calculer les dimensions dont vous aurez besoin si vous voulez garder les proportions intactes.
  2. Utilisez Image.copy() pour obtenir une copie de l'image.

Comme ceci:

original = parser.close() 
... 

thumb1 = original.copy() 
size = (75,75) 
thumb1.thumbnail(size, Image.ANTIALIAS) 
... 

thumb2 = original.copy() 
thumbnail2 = original.resize(size2, Image.ANTIALIAS) 
... 

De cette façon, l'original ne sera pas modifié et vous pouvez obtenir autant de copies que vous avez besoin.

+0

Merci, image.copy() était exactement ce dont j'avais besoin. Je suis trop ridicule pour faire défiler vers le bas et noter cette méthode dans les docs, donc j'essayais de cloner moi-même l'objet UploadedFile et de le réutiliser :) – orokusaki

0

Je suppose qu'il est défaillant sur le image = parser.close() ligne avec un IOError. donc il y a probablement quelque chose qui ne va pas avec la manière dont ImageFile obtient les données de l'image. Avez-vous essayé de faire la lecture à partir d'un fichier local à la place?

Si l'analyseur parvient à décoder une image, il renvoie un objet Image. Sinon, cette méthode déclenche une exception IOError.

Source.

2

Une solution plus simple que de copier l'image originale est de réinitialiser le pointeur au lieu de fichiers entre les appels à la miniature (...) comme ceci:

original.seek(0) 
+0

Oh, sympa! Cela permettra d'économiser beaucoup de mémoire trop bien? – orokusaki

Questions connexes