Enregistrement de GIF animés à l’aide de PIL (l’image enregistrée ne s’anime pas)

J’ai Apache2 + PIL + Django + X-sendfile. Mon problème est que lorsque je sauvegarde un fichier GIF animé, celui-ci ne sera pas “animé” lorsque je transmettrai via le navigateur.

Voici mon code pour afficher l’image située en dehors du répertoire accessible au public.

def raw(request,uuid): target = str(uuid).split('.')[:-1][0] image = Uploads.objects.get(uuid=target) path = image.path filepath = os.path.join(path,"%s.%s" % (image.uuid,image.ext)) response = HttpResponse(mimetype=mimetypes.guess_type(filepath)) response['Content-Disposition']='filename="%s"'\ %smart_str(image.filename) response["X-Sendfile"] = filepath response['Content-length'] = os.stat(filepath).st_size return response 

METTRE À JOUR

Il s’avère que cela fonctionne. Mon problème est lorsque j’essaie de télécharger une image via une URL. Cela ne sauve probablement pas la totalité du GIF?

 def handle_url_file(request): """ Open a file from a URL. Split the file to get the filename and extension. Generate a random uuid using rand1() Then save the file. Return the UUID when successful. """ try: file = urllib.urlopen(request.POST['url']) randname = rand1(settings.RANDOM_ID_LENGTH) newfilename = request.POST['url'].split('/')[-1] ext = str(newfilename.split('.')[-1]).lower() im = cSsortingngIO.SsortingngIO(file.read()) # constructs a SsortingngIO holding the image img = Image.open(im) filehash = checkhash(im) image = Uploads.objects.get(filehash=filehash) uuid = image.uuid return "%s" % (uuid) except Uploads.DoesNotExist: img.save(os.path.join(settings.UPLOAD_DIRECTORY,(("%s.%s")%(randname,ext)))) del img filesize = os.stat(os.path.join(settings.UPLOAD_DIRECTORY,(("%s.%s")%(randname,ext)))).st_size upload = Uploads( ip = request.META['REMOTE_ADDR'], filename = newfilename, uuid = randname, ext = ext, path = settings.UPLOAD_DIRECTORY, views = 1, bandwidth = filesize, source = request.POST['url'], size = filesize, filehash = filehash, ) upload.save() #return uuid return "%s" % (upload.uuid) except IOError, e: raise e 

Des idées?

Merci!

Wenbert

D’où vient cette classe d’ Image et que fait Image.open ?

J’imagine que cela permet de nettoyer les données d’image (ce qui est une bonne chose), mais ne sauve que la première image du Gif.

Modifier:

Je suis convaincu que c’est un problème avec PIL. La documentation PIL sur GIF dit:

PIL lit les versions GIF87a et GIF89a du format de fichier GIF. La bibliothèque écrit les fichiers GIF87a codés en longueur.

Pour vérifier, vous pouvez écrire le contenu de im directement sur le disque et comparer avec l’image source.

Le problème consiste à enregistrer une version ouverte de PIL de l’image. Lorsque vous l’enregistrez via PIL, il ne sauvegardera que la première image.

Cependant, il existe une solution simple: créez une copie temporaire du fichier, ouvrez-la avec PIL, puis, si vous détectez qu’il s’agit d’un fichier GIF animé, enregistrez simplement le fichier d’origine, pas la version ouverte.

Si vous enregistrez le fichier GIF animé original puis le retransmettez dans votre réponse HTTP, il sera animé par le navigateur.

Exemple de code pour détecter si votre object PIL est un GIF animé:

 def image_is_animated_gif(image): # verify image format if image.format.lower() != 'gif': return False # verify GIF is animated by attempting to seek beyond the initial frame try: image.seek(1) except EOFError: return False else: return True