Description
Ici, il n’est pas question de demander au serveur web nginx de modifier/créer à la volée des images au format WebP.
Pour ceux qui ne savent pas ce qu’est le format WebP, sachez que c’est un conteneur d’image matricielle, développé par… Google. Il permet de faire d’obtenir des images plus légères, qu’elles ne le seraient au format JPEG. cf: la section Documentation ci-dessous !
Installation
Bref, cela nécessite d’installer sur votre système d’exploitation la bibliothèque nécessaire :
- sous Linux : le paquet webp
- sous OpenBSD : le paquet libwebp
:$ convert "${file}" "${file}.webp"Utilisation
Pour transformer une image jpg, png, voire tiff au format, il suffit d’appeler la bibliothèque cwebp, très simplement :
cwebp -m 0 -mt "${image}" -o "${image}.webp"
Quant aux images gif, elles sont converties grâce à la bibliothèque gif2wepb :
gif2webp -m 0 -mt "${image}" -o "${image}.webp"
Veuillez lire le manpage correspondant pour connaître les différentes options de la bibliothèque :
:$ man cwebp:$ man gif2webp
Voici le code que j’utilise personnellement :
_webp() {
if [ ! -f "${file}.webp" ]; then
case "$(file -b "${file}")" in
'GIF'*)
gif2webp -m 0 -mt "${file}" -o "${file}.webp"
;;
'JPEG'|'PNG'|'TIFF'*)
cwebp -exact -lossless -m 0 -mt -progress "${file}" -o "${file}.webp"
;;
esac
fi;
}
Que fait ce code ?
Dans les faits, il teste :
- l’existence du fichier ayant l’extension de fichier
.webp - puis détermine le type du fichier et appelle la bonne bibliothèque selon le format détecté.
Par soucis de simplicité et de lecture, il génére une image au format webp,
portant l’extension .webp, ajouté à son nom de fichier originel, tel que
image.jpg.webp, pour l’exemple.
Tu verras, toi mon lecteur, que cela nous facilite la configuration de
nginx, par la suite.
Ensuite, je parcoure un répertoire d’image par le biais de la fonction
find, qui appelle la fonction _webp déclarée ci-dessus, tel que :
find . -type f -a \( \
-name "*.gif" -o -name '*.jpg' -o -name '*.jpeg' -o -name '*.png' -o -name '*.tiff' \
\) | while read -r file; do _webp; done
Voici le script shell que j’utilise :
#!/bin/bash
#set -x
clear
########################################################################
###
##
#
# Author: Stéphane HUC
# mail: devs@stephane-huc.net
# gpg:fingerprint: CE2C CF7C AB68 0329 0D20 5F49 6135 D440 4D44 BD58
#
# License: Public Domain
#
# Git:
#
# Date: 2020/10/03
#
##
###
########################################################################
##
# Convert to webp images
##
########################################################################
#ROOT="$(dirname "$(readlink -f -- "$0")")"
########################################################################
_webp() {
if [ ! -f "${file}.webp" ]; then
case "$(file -b "${file}")" in
'GIF'*)
gif2webp -m 0 -mt "${file}" -o "${file}.webp"
;;
'JPEG'|'PNG'|'TIFF'*)
cwebp -exact -lossless -m 0 -mt -progress "${file}" -o "${file}.webp"
;;
esac
fi;
}
main() {
find . -type f -a \( \
-name "*.gif" -o -name '*.jpg' -o -name '*.jpeg' -o -name '*.png' -o -name '*.tiff' \
\) | while read -r file; do _webp; done
}
########################################################################
main
Celui-ci est aisément modifiable pour l’utiliser sous tout autre shell.
De deux manières l’une, j’utilise ce script soit en l’appelant individuellement, soit par le biais de mon script de déploiement de mes fichiers vers le serveur web.
Ainsi, en sus des images aux formats originels, j’y dépose celles au format webp. ;-)
Configuration
Modifions la configuration de nginx, afin de lui signifier que quand il est demandé des images au format jpeg|gif|png|tiff, il essaye de diffuser celles au format webp, si elles existent.
⇒ Dans le contexte http du serveur, ajoutons une map afin de déclarer
une variable $webp_suffix qui nous permettra de reconnaître une image
ayant l’extension .webp.
map $http_accept $webp_suffix {
webp_suffix "";
"~*webp" ".webp";
}
⇒ Le script suivant est à inclure dans le contexte de la déclaration server
de votre configuration d’hôte virtuel.
location ~ /*.(jpe?g|gif|png|tiff)$ {
access_log off;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
add_header Pragma public;
add_header Vary "Accept-Encoding";
expires max;
log_not_found off;
try_files $uri$webp_suffix $uri =404;
}
location ~ /*.(gif|jpe?g|png|tiff).webp {
access_log off;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
add_header Content-Type image/webp;
add_header Pragma public;
add_header Vary "Accept-Encoding";
default_type image/webp;
expires max;
# normalement, non nécessaire car déclaré dans les types mimes reconnus par nginx
types {
image/webp webp;
}
}
Ce que fait cette configuration ?
- Lorsqu’un appel est fait vers une image, au format sus-mentionné :
- aucune inscription au journal n’est faite
- envoie des entêtes HTTP nécessaires pour une bonne “publication” par le serveur vers le client.
- essaie d’envoyer l’image portant l’extension
.webp, suffixé au nom de l’image appelée, sinon retourne logiquement une erreur 404.
remarque l’utilisation de la variable$webp_suffixà la ligne 13.
- L’appel à une image portant l’extension
.webp:- n’est pas journalisé
- envoie les entêtes HTTP nécessaires
- définit correctement le bon type mime.
Et, voilà !!!
Reste plus qu’à tester votre configuration avec nginx et redémarrer le service correspondant - par exemple, pour OpenBSD :
:# nginx -t
:# rcctl restart nginx
HTML
Pour finir, modifiez votre code HTML à-propos de la gestion des images, tel que, par exemple pour une image jpeg, à minima :
<picture>
<source srcset="/img/{{ $img }}.jpg.webp" type="image/webp">
<img alt="texte" src="/img/{{ $img }}.jpg" type="image/jpeg">
</picture>
Ce qui permettra aux clients web qui supportent le format webp de demander l’affichage de ce format en lieu et place…
Essai
Test avec mon Logo :
Ainsi, selon le support du client web, vous recevrez soit le format WebP, sinon le fichier “source” png…
Documentation
- WebP WP
- A new image format for the Web : site officiel
- le site caniuse.com : https://caniuse.com/webp