Vous êtes à Accueil > Nos techniques > Compresser vos images

Passer le menu Aller au pied de page

Licences Joueb English version Accessibilité

Compresser vos images

Une courte page de mémo pour indiquer quelques ressources intéressantes pour comprendre cette question, et pour quelle solution nous avons opté.

Il s’agit bien évidemment ici de compression sans perte : vous pouvez réduire la taille de la plupart de vos fichiers images sans perdre en qualité du tout (mais en effaçant les meta-données, cependant).

Nous évoquons également brièvement comment différer le chargement de vos images.

Sommaire :RessourcesLa solution employéeTraiter les images par lotDifférer le chargement des images

 

Quelques ressources pour comprendre…

Pour comprendre dans quel cas utiliser le format JPEG, PNG ou GIF, comment préparer vos images et captures d’écran, ce tutoriel du Hollandais volant paraît tout indiqué. Notez qu’il existe un greffon (aussi chez github) pour The Gimp qui automatise une partie du travail et vous permets d’exporter facilement vos images dans le format le plus approprié.

Pour savoir quel compresseur de fichiers PNG privilégier, vous pouvez consulter un test très complet ou ce comparatif entre pngcrush et optipng. Enfin, vous pouvez vous référer à ce guide très complet si vous voulez une compréhension théorique de la compression des fichiers PNG. Le guide le plus complet, synthétique mais qui couvre tous les formats, reste néanmoins celui d’Addy Osmani.

Il existe différents scripts et logiciels pour compresser vos images sur la toile, de qualité très variable. Trimage sera une excellente solution pour ceux qui préférent une interface graphique intelligente qui fait le travail tout seul, encore que le manque de possibilité de configuration et quelques bogues puissent en dissuader certains.

 

Comment fait-on chez micr0lab ?

Pour lister les images présentes sur votre site, ouvrez un terminal et faîtes quelque chose comme

find /dossier/du/site/ \( -name dossier-a-exclure -prune \) -o -iname "*.jpg" -o -iname "*.png"\
        -o -iname "*.jpeg" -o -iname "*.tif*" -o -iname "*.gif"

Image Optim est un logiciel bien pensé qui emploie plusieurs librairies de codage, choisit celles appropriées à votre format, compare les résultats. Ce logiciel n’existe que pour Mac, il nous faut donc nous tourner vers image_optim pour un portage sous linux. Nous détaillons rapidement ci-dessous comment installer et employer ce logiciel, bien que sa page soit très complète.

Il vous faut d’abord installer gem, vous pouvez par exemple consulter ce billet pour voir comment faire : votre gestionnaire de paquets devrait gérer ça facilement.

Il vous faut ensuite installer les dépendances, à savoir advancecomp, gifsicle, jhead, jpegoptim, libjpeg-progs, optipng, pngcrush. Il faut également installer pngout, même si c’est déclaré comme étant optionnel (consultez ce fil pour comprendre pourquoi). Si vous rencontrez un problème difficile à décrypter à l’exécution du logiciel (genre undefined method `inject' for nil:NilClass), vous pouvez essayer d’appeler le programme avec les options --no-threads et -v.

Pour installer pngout, récupérez le binaire qui vous convient à http://www.jonof.id.au/kenutils (dans mon cas, la version statique i686), renommer (si besoin) le binaire en pngout et incluez le répertoire qui contient cet exécutable à votre « path ». Vous pouvez aussi simplement appeler image_optim en précisant ce chemin en préambule : PATH="$PATH:/dossier/de-pngout" image_optim nom_petit.png

Il ne vous reste plus qu’à appeler ce programme avec l’option récursive, et tous vos png, gif, jpg et svg seront optimisés !

Dans notre cas, cela donne

PATH="$PATH:/donnees/0101/Internet/compression_images/" image_optim -rv /donnees/micr0lab/
 

Traiter des images par lot

L’interface en ligne de commande (ici, sous Linux) est un excellent moyen de traiter simplement des images par lot. Cependant, il faut être extrêmement vigilants : une fausse manipulation, et vos fichiers pourraient être perdus! Employez les commandes suivantes avec discernement, et précaution.

Par exemple, si vous voulez convertir les extensions en charactères bas de casse, faîtes

for i in *.JPG; do mv "" "${i/.JPG}".jpg; done
for i in *.JPEG; do mv "" "${i/.JPEG}".jpeg; done
for i in *.PNG; do mv "" "${i/.PNG}".png; done

Si vous voulez vraiment faire du renommage de façon avancé, vous pouvez jeter un œil à ce script plus évolué.

Si vous voulez anonymiser vos photos, employez ExifTool et faîtes

for i in *.(jpg|jpeg|png); do echo "Processing "; exiftool -all= "" -overwrite_original; done ;

Pour les commandes suivantes, nous employons mogrify, convert et montage, logiciels faisant partie d’imagemagick. Pour redimensionner au format 960 pixels sur 640 pixels

mogrify -resize 960x640 *.(jpg|jpeg|png)

Pour reduire de 20%,

convert -resize 20% *.(jpg|jpeg|png)

Pour renommer aléatoirement des fichiers,

for f in *.jpg; do   mv "$f" $RANDOM-"$f"; done

Pour créer une frise,

montage *.(jpg|jpeg|png) -mode Concatenate  -tile 6x5 -size 400x400 -density 30 frise.jpeg

Pour « coller » horizontalement quatre images, et ajouter un peu de marge (transparente) entre elles :

convert -bordercolor transparent \( cc_25.png -border 5x0 \) \
  \( by_25.png -border 10x0 \) \( nc_25.png -border 10x0 \) \
  \( nd_25.png -border 10x0 \) +append licence.png
 

Différer le chargement de vos images

Vos images sont allégées, mais il n’en reste pas moins que toutes les charger peut consommer beaucoup de bande passante. Il existe bien évidemment la technique des sprites, mais elle ne peut s’appliquer à toutes les images. Nous nous concentrons donc ici sur des images qui ne sont affichées que sur une page de taille conséquente. L’astuce sera de ne charger les images que lorsque l’internaute les affiche.

Il existe plusieurs greffons jQuery pour cela :

micr0lab emploie actuellement lazysizes, mais nous documentons ci-dessous comment employer Lazy Load (le code est essentiellement le même).

Sans altérer le html

Le principal inconvénient de ces greffons est qu’ils nécessitent d’altérer votre code html. Si vous ne le souhaitez pas, vous pouvez vous tourner vers la version 1.5.0 de Lazy Load (js), moins efficace avec les naviguateurs modernes mais ne nécessitant par d’altérer le code html.

Après avoir chargé votre bibliothèque jQuery et Lazy Load, ajoutez simplement à la fin de votre header :

<script type="text/javascript">
        jQuery(function() {
        if (navigator.platform == "iPad" || navigator.platform == "iPhone") return;
        jQuery("img").lazyload({
        placeholder : "images/internet/place.gif",
        effect: "fadeIn",
        });
        });
</script>

Vous devez veiller à bien renseigner le chemin du petit .gif vide que voici (gif).

Et voilà, rien à faire, aucune configuration, les images se chargeront au besoin.

En altérant le html

Il y a tout de même eu pas mal d’améliorations au fil des version de lazyload, aussi pouvez-vous envisager de modifier votre code html (si ne plus être valide ne vous ennuie pas). En essayant de rester respectueux des choix de l’internaute, bien évidemment. C’est-à-dire que l’on proposera une alternative avec noscript au cas où le navigateur a désactivé le javascript.

Cela passe par trois étapes : charger le javascript, ajouter un peu de css pour ne pas afficher à la fois la version avec javascript et la version sans javascript, et enfin se simplifier la tâche en automatisant un peu tout ça avec du php.

<script src="tech/js/lazyload-1-9-3.js"></script>
<script type="text/javascript">
        $(function() {
                $("img.lazy").show().lazyload();
                });
        $("img.lazy").lazyload({
                threshold : 1000,
                effect : "fadeIn"
        });
</script>
.lazy {display: none;}
function image_lazy($url, $alt, $title, $classe){
 $info = getimagesize($url);
 echo '<img data-original="'.$url.'" '.$info[3].'';
 if (isset($alt)) {echo ' alt="'.$alt.'"';}
 if (isset($title)) {echo ' title="'.$title.'"';}
 if (isset($classe)){echo ' class="'.$classe.' lazy"';}
 echo '/>';
 echo '<noscript><img src="'.$url.'" '.$info[3].'';
 if (isset($alt)) {echo ' alt="'.$alt.'"';}
 if (isset($title)) {echo ' title="'.$title.'"';}
 if (isset($classe)){echo ' class="'.$classe.'"';}
 echo '></noscript>';
        }

Tout ceci fait, il vous suffit d’écrire

<?image_lazy(
        "chemin/image.jpg",
        "L’attribut alt.",
        "Le titre",
        "La_classe")
?>

Pour obtenir automatiquement

<img
        data-original="chemin/image.jpg"
        width="502" height="269"
        alt="L’attribut alt."
        title="Le titre"
        class="lazy La_classe"/>
<noscript>
        <img
                src="chemin/image.jpg"
                width="502" height="269"
                alt="L’attribut alt."
                title="Le titre"
                class="La_classe">
</noscript>

Et assurer à la fois un chargement progressif élégant, une compatibilité maximale, et une utilisation simple. Cendant, notez bien que le rendu n’est plus valide pour cause d’attribut src manquant, et cela ne semble pas évident à corriger.

 

Contact :

Contact Plan Lettre F.a.q. C.G.U.