Script Pour Feignasse : optimisation_images.sh

Quitte à migrer depuis l'usine à gaz Wordpress vers Pelican, autant faire en sorte de vraiment tout optimiser. Et les images sur le web ont tendance à prendre beaucoup (trop) de place. Même si je ne suis pas un blog photos, je me suis dit que vous faire gagner un peu de temps de chargement ne ferait pas de mal (et ça me permet de faire un script - tout le monde y gagne).

Après avoir écumé le web à la recherche de l'outil parfait, je suis tombé sur ceux-là :

C'est finalement l'option n°2 que j'ai retenu. Installation simple et rapide sur debian : apt install optipng jpegoptim, beaucoup de combinaisons possibles, et efficacité au rendez-vous.

jpegoptim

convert a aussi les qualités citées plus haut, mais en comparant sur une photo de 3,5 Mo :

convert -quality 50% DSC_0219.jpg DSC_0219_2.jpg

1,5M    DSC_0219_2.jpg
3,5M    DSC_0219.jpg

Avec jpegoptim :

find . -iname '*.jpg' -print0 | xargs -0 jpegoptim --max=50 --strip-all --preserve --totals

1,3M    DSC_0219.jpg

Ça ne se joue pas à grand chose, mais sur des centaines de photos... Alors, je vous l'accorde (en La mineure), je triche un peu : avec jpegoptim j'enlève aussi les données EXIF.

La commande ci-dessus :

optipng

Sur une image de 205.9Ko :

optipng -o7 -strip all -preserve Capture\ d\'écran\ de\ 2016-02-27\ 22\:56\:37.png
** Processing: Capture d'écran de 2016-02-27 22:56:37.png
1122x685 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Stripping metadata...
Input IDAT size = 205468 bytes
Input file size = 205878 bytes

Trying:
  zc = 9  zm = 9  zs = 0  f = 0     IDAT size = 148855

Selecting parameters:
  zc = 9  zm = 9  zs = 0  f = 0     IDAT size = 148855

Output IDAT size = 148855 bytes (56613 bytes decrease)
Output file size = 148912 bytes (56966 bytes = 27.67% decrease)

148K    Capture d'écran de 2016-02-27 22:56:37.png

-o7 est la compression maximale, elle prendra donc du temps. Si vous avez beaucoup de png, armez vous de patience.

Les gifs

Concernant les gifs, la solution est de les passer en vidéos. Ainsi, un gif de 3.1Mo (c'est déjà du beau gif) devient un .mp4 de 699.7ko (non, je ne mettrai pas 700 !). Je suis par exemple passé d'un dossier contenant 12.6Mo de gifs, à 2.5Mo.

La solution consiste à passer par ffmpeg, et je vous laisse voir les détails ici.

Ensuite :

<video autoplay="autoplay" loop="loop" width="600" height="500">
  <source src="{filename}/images/posts/2016/03/booya.gif.mp4" type="video/mp4" /></video>

Donne :

Le script

Je supprime tous les fichiers .gif dans ce script. Si vous souhaitez les garder, enlevez la ligne rm *.gif. Et comme d'habitude, je ne serais tenu responsable si vous faites n'importe quoi avec ce script. Faut savoir ce qu'on fait.

#!/bin/bash
#
#     Script qui optimise les images dans le répertoire images
#     (merci http://how2linux.net/2014/12/18/script-optimize-images-faster-loading-websites-centos
#     et http://rigor.com/blog/2015/12/optimizing-animated-gifs-with-html5-video)
#

SOURCE=/home/spf/virtualenvs/pelican/content/images/posts

if [ ! -d "$SOURCE" ]; then
   echo "Ce dossier '$SOURCE' n'existe pas !"
   exit 2;
else
  cd $SOURCE
  cd $(ls -t | head -n 1)
  cd $(ls -t | head -n 1)
  find . -atime -2 -iname '*.png' -print0 | xargs -0 optipng -o7 -strip all -preserve
  find . -atime -2 -iname '*.jpg' -print0 | xargs -0 jpegoptim --max=60 --strip-all --preserve --totals
  for i in *.gif; do
    ffmpeg -i $i -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" $i.mp4
  done
  rm *.gif
fi

Le chemin vers mes photos est du style : /home/spf/virtualenvs/pelican/content/images/posts/2016/03. Le script se déplace dans le dossier indiqué par $SOURCE puis dans le dernier dossier accédé deux fois de suite (2016 puis 03 ici).

Pour éviter de rescanner toutes les images du dossier, j'ai ajouté -atime -2, pour que le script ne s'occupe que des images dont le dernier accès est inférieur à 2 jours.

Désormais, lorsque j'écris un post avec des images, je lance le script avant d'envoyer.

diaspora*
Retour maison