web-dev-qa-db-fra.com

Compression sans perte d'images sur django

Je fais de l'optimisation et Google recommande la compression sans perte des images, à la recherche d'un moyen de l'implémenter dans Django.

Voici les images qu'ils ont spécifiées, je pense que pour que cela soit fait efficacement, il doit être implémenté à l'échelle du système en utilisant éventuellement une classe de middleware se demandant si quelqu'un l'a déjà fait auparavant. Voici le lien vers google analytics pour pagespeed https://developers.google.com/speed/pagespeed/insights/?url=www.kenyabuzz.com

Optimiser les images Un formatage et une compression corrects des images peuvent économiser de nombreux octets de données. Optimisez les images suivantes afin de réduire leur taille de 627,3 Ko (réduction de 74%).

Losslessly compressing http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg could save 594.3KiB (92% reduction).
Losslessly compressing http://www.kenyabuzz.com/media/uploads/clients/new_tribe_2.jpg could save 25KiB (44% reduction).
Losslessly compressing http://www.kenyabuzz.com/…a/uploads/clients/EthiopianAirlines2.jpg could save 3KiB (22% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/images/Nightlife.Homepage.jpg could save 1.3KiB (2% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/img/social/blog.png could save 1.1KiB (43% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/img/social/Twitter.png could save 969B (52% reduction).
Losslessly compressing http://www.kenyabuzz.com/…der-Board---Email-Signature--Neutral.jpg could save 920B (2% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/img/social/youtube.png could save 757B (31% reduction).
21
user4910881

La compression sans perte http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg pourrait économiser 594,3 Ko (réduction de 92%).

Tout d'abord, les informations dans les journaux sont plutôt trompeuses car il est impossible de compresser les images de 92% en utilisant un format sans perte (sauf dans certains cas comme les images en une seule couleur, les formes géométriques de base comme les carrés, etc.). Lisez cette réponse et cette réponse pour plus d'informations. Vraiment, lisez-les, les deux sont d'excellentes réponses.

Deuxièmement, vous pouvez utiliser des formats de compression avec perte "sans perte de qualité" - les différences sont si subtiles que l'œil humain ne s'en rend même pas compte.


J'ai donc téléchargé une image du site Web que vous optimisez à partir de ce lien: http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg

J'ai ouvert ma console Python et écrit ceci:

>>> from PIL import Image

>>> # Open the image
>>> im = Image.open("kenya_buzz_2.jpg")
>>> # Now save it
>>> im.save("kenya_buzz_compressed.jpg", format="JPEG", quality=70)

Cela a créé une nouvelle image sur mon disque. Voici les deux images.

Original (655,3 Ko)

original image


Compressé (22,4 Ko ~ 96% de réduction @ qualité = 70)

compressed image using Python


Vous pouvez jouer avec l'option quality. Comme, la valeur de 80 vous donnera une image de meilleure qualité mais avec une taille un peu plus grande.


Compression d'images dans Django

Comme c'est une question assez populaire, j'ai décidé d'ajouter un exemple de code pour compresser les images dans Django.

Ce code fonctionne pour Django> = 1.7.

from io import BytesIO
from PIL import Image
from Django.core.files import File


def compress(image):
    im = Image.open(image)
    # create a BytesIO object
    im_io = BytesIO() 
    # save image to BytesIO object
    im.save(im_io, 'JPEG', quality=70) 
    # create a Django-friendly Files object
    new_image = File(im_io, name=image.name)
    return new_image

Et voici comment vous pouvez utiliser la fonction compress ci-dessus dans votre Django (ou n'importe où):

# models.py

class MyModel(...):
    image = models.ImageField(...)

    def save(self, *args, **kwargs):
        # call the compress function
        new_image = compress(self.image)
        # set self.image to new_image
        self.image = new_image
        # save
        super().save(*args, **kwargs)

C'est fondamentalement ça. C'est un code assez basique. Vous pouvez améliorer le code en compressant l'image uniquement lorsque l'image change, pas à chaque fois que le modèle est enregistré.

37
xyres

Vous devriez essayer Django Easy Thumbnails app , il a quelques options pour ajouter un post-traitement pour optimiser les images téléchargées: Documentation PostProcessor

Je l'utilise en production sur plusieurs projets. Cela fonctionne bien, la taille de l'image est nettement plus petite et le chargement de la page beaucoup plus rapide .

3
The Django Ninja

Je n'ai aucune expérience avec cela, cependant, picopt semble complet. Il s'appuie largement sur des outils externes pour effectuer l'optimisation, il peut donc être difficile à configurer dans des environnements de serveur contraints ou hébergés.

Autre que cela, essayez de googler "optimisation d'image python". Il existe quelques autres liens qui suggèrent qu'une solution basée sur PIL pourrait être possible, par exemple:

  1. Comment réduire la taille du fichier image en utilisant PIL
  2. Optimisation d'image (Google App Engine avec Python)
2
mhawke