Optimiser les PNG avec Oxipng en ligne de commande et en Rust
Pour compresser un PNG avec Oxipng tout en conservant le fichier original, utilisez
--out avec un nom de fichier différent.
Le guide ci-dessous prévisualise le résultat, écrit une copie optimisée, puis effectue la même
opération en Rust. Il utilise des PNG ordinaires, non animés, et laisse les transformations
facultatives avec perte désactivées.
L’optimisation sans perte des PNG peut modifier la compression, le filtrage, l’organisation de la palette et la représentation des couleurs sans modifier les valeurs des pixels décodés. Une empreinte numérique différente ne signifie donc pas que l’image a perdu en qualité. Elle ne prouve pas non plus que toutes les métadonnées ont été conservées. Gardez le fichier source si vous avez besoin d’un original à des fins d’archivage.
Installer Oxipng
Ces exemples Bash ont été testés sous Linux avec Rust et Cargo 1.98.1 ainsi qu’Oxipng 10.2.1.
Vous devez disposer de Cargo dans votre PATH, d’un compilateur C et d’un
éditeur de liens pour la dépendance native de compression. Le répertoire des exécutables de Cargo
doit aussi figurer dans votre PATH. Oxipng 10.2.1 indique que
Rust 1.88.0 est la version minimale requise.
cargo install oxipng --version 10.2.1 --locked &&
oxipng --version
La commande de vérification de version devrait afficher oxipng 10.2.1.
Si elle affiche une autre version, vérifiez quel exécutable votre shell trouve avant de continuer.
cargo install compile par défaut en mode release ;
--locked utilise le fichier de verrouillage des dépendances inclus dans la crate.
Optimiser un PNG
Placez votre PNG dans le répertoire courant sous le nom input.png.
Commencez par prévisualiser l’optimisation sans rien écrire :
oxipng -o 4 --dry-run -v -- input.png
--dry-run effectue tout de même le travail d’optimisation ; seule l’écriture du
résultat est omise. La version 10
a remplacé l’ancienne option --pretend.
Pour enregistrer le résultat séparément et comparer les tailles des fichiers :
oxipng -o 4 -v --out optimized.png -- input.png &&
wc -c input.png optimized.png
Le fichier input.png reste intact.
Tout fichier optimized.png existant est remplacé sans confirmation, y compris
lors d’une nouvelle exécution non interactive. Choisissez un nouveau nom de destination si vous devez
conserver un résultat précédent. Le répertoire parent de la destination doit déjà exister.
Le préréglage quatre constitue un point de départ, sans garantie de réduction de taille. Les niveaux disponibles vont de zéro à six ; le niveau par défaut est deux. Les préréglages plus élevés demandent un travail de recherche plus important, mais ne garantissent pas un résultat plus petit. Un PNG déjà optimisé peut ne présenter aucune réduction de taille. Avec ces réglages, un fichier de sortie distinct est tout de même écrit, avec les octets d’origine lorsqu’Oxipng ne peut pas faire mieux. Sans destination distincte, le fichier d’entrée reste intact dans ce cas.
Oxipng utilise par défaut les processeurs logiques disponibles. Ajoutez --threads 4
pour limiter ses threads de travail sur une machine partagée. Consultez le
manuel de la CLI correspondant à cette version
pour obtenir la liste complète des options.
Choisir les éléments à préserver
Trois types de préservation distincts sont importants ici :
| Réglage | Signification |
|---|---|
Sans --alpha | Conserver les valeurs RGB, même dans les pixels entièrement transparents. Ajouter --alpha autorise la modification de ces couleurs invisibles pour la compression ; le résultat est visuellement sans perte, mais les données des pixels changent. |
Sans --strip | Conserver les métadonnées PNG qui restent valides après l’optimisation, sous réserve des exceptions ci-dessous. |
--preserve | Tenter de conserver les permissions et l’horodatage de modification du fichier dans le système de fichiers. Ce réglage ne contrôle pas les métadonnées PNG et ne conserve pas l’horodatage d’accès. |
Les options de la bibliothèque laissent également désactivées par
défaut l’optimisation du canal alpha et la conversion avec perte de 16 à huit bits. N’ajoutez pas
--scale16 si vous devez conserver les valeurs des pixels sans perte.
La conservation par défaut des métadonnées n’équivaut pas à une préservation exacte à des fins
d’archivage. Oxipng supprime bKGD, sBIT et
hIST si un changement de type de couleur ou de profondeur de bits les rend
invalides. Il supprime aussi par défaut les blocs C2PA caBX et les blocs
Apple iDOT. Un profil ICC intégré peut être recompressé. Ces comportements
sont décrits dans l’implémentation de la gestion des blocs
et dans le manuel de la CLI.
N’utilisez --strip safe que si vous souhaitez supprimer les informations auxiliaires
telles que le texte et les données EXIF. Cette option conserve certains blocs liés à l’affichage,
notamment sRGB et pHYs, mais ne garantit pas la
conservation de toutes les métadonnées. --strip all va plus loin et peut supprimer
des informations de gestion des couleurs, ce qui modifie l’affichage de l’image. Aucune de ces
options n’est nécessaire pour les exemples présentés ici.
Si vous souhaitez délibérément remplacer votre fichier d’entrée tout en conservant ses permissions et son horodatage de modification, utilisez :
oxipng -o 4 --preserve -- input.png
Cette opération modifie directement le fichier : conservez une copie de sauvegarde avant de l’exécuter. Les attributs sont conservés dans la mesure du possible ; Oxipng affiche un avertissement s’il ne peut pas restaurer un attribut.
Traiter un dossier par lots
Pour un répertoire de ressources PNG que vous acceptez de remplacer, exécutez :
find ./images -type f -name '*.png' -exec oxipng -o 4 --preserve -- {} +
Cette commande parcourt les sous-répertoires et transmet correctement les noms de fichiers contenant
des espaces. Elle sélectionne les extensions .png en minuscules et modifie
les fichiers directement ; une nouvelle exécution porte sur ces mêmes fichiers. Ajoutez
--dry-run aux arguments d’Oxipng pour obtenir un aperçu. Travaillez sur une copie
du répertoire de ressources si vous devez conserver les originaux.
Intégrer Oxipng à votre code Rust
Créez un nouveau projet et fixez la même version de la crate :
cargo new --bin --vcs none png-optimize &&
cd png-optimize &&
cargo add oxipng@=10.2.1
Ne poursuivez qu’une fois cette opération réussie. Si le répertoire png-optimize
existe déjà, cargo new échoue ; choisissez un nouveau nom de projet plutôt que de
supprimer un projet existant. Conservez le fichier Cargo.lock généré pour garder
les versions résolues des dépendances.
Placez une copie de votre PNG dans le répertoire de ce projet sous le nom
input.png. Remplacez le fichier src/main.rs généré par ce
programme complet :
use oxipng::{optimize, InFile, Options, OutFile};
use std::path::PathBuf;
fn main() -> Result<(), oxipng::PngError> {
let input = InFile::Path(PathBuf::from("input.png"));
let output = OutFile::from_path(PathBuf::from("output.png"));
let options = Options::from_preset(4);
let (before, after) = optimize(&input, &output, &options)?;
println!("{before} -> {after} bytes: output.png");
Ok(())
}
Depuis png-optimize, exécutez :
cargo run --release
Le programme lit input.png, dont le chemin est relatif au répertoire courant,
écrit output.png et affiche les nombres d’octets d’entrée et de sortie renvoyés par
optimize. Si le fichier
output.png existe déjà, il est remplacé sans confirmation. Des nombres d’octets
identiques constituent un résultat valide, et non un échec.
OutFile::from_path choisit un fichier distinct et ne
demande pas la conservation des attributs. Utilisez OutFile::None pour une exécution
à blanc avec la bibliothèque, ou OutFile::Path { path: Some(PathBuf::from("output.png")), preserve_attrs: true } si vous avez besoin de conserver sur
le fichier de sortie les permissions et l’horodatage de modification du fichier d’entrée.
Gérer les erreurs d’entrée lors d’une compilation
En cas d’entrée manquante ou mal formée, la CLI se termine avec un statut d’échec. L’exemple Rust
propage PngError par l’intermédiaire de ? ; il se
termine donc lui aussi avec un statut d’échec et n’affiche pas les nombres d’octets normalement
affichés en cas de réussite. Exécutez-le une fois sans input.png pour observer ce
chemin d’erreur. Un répertoire de sortie manquant peut aussi faire échouer l’opération, tout comme
une erreur de permission d’écriture.
Vérifiez le code de sortie avant d’utiliser un fichier de sortie : un ancien fichier de sortie peut encore être présent après une exécution en échec. Une optimisation réussie n’implique pas non plus une réduction de taille. Dans un processus de génération des ressources, traitez les échecs comme des erreurs et enregistrez les nombres d’octets réels plutôt que d’exiger une réduction fixe.
