Introduction
J’ai un disque sur lequel je garde des images que j’enregistre depuis les réseaux sociaux, souvent des infographies. Dans ce tutoriel, nous allons utiliser bash, ImageMagick et R pour effectuer le ménage dans ce répertoire.
Il y a souvent des pages que j’enregistre au complet, mais seulement pour garder les photos qu’elles contiennent. Celles-ci contiennent souvent des miniatures et des images utilisées pour le thème de la page.
Bref, au fil des années, le répertoire devenait un fouillis.
Détecter la résolution des images avec ImageMagick
Je cherchais donc un moyen de conserver seulement les grandes images, celles avec une résolution de 720×720 minimum.
Donc, ma première étape a été de trouver un moyen de lister la résolution de toutes les images du répertoire.
J’ai fait ceci en utilisant identify, un outil de la suite ImageMagick.
identify InvertedIndex.jpg
La sortie de ce logiciel ressemble à ceci:
InvertedIndex.jpg JPEG 588x447 588x447+0+0 8-bit sRGB 36166B 0.000u 0:00.000
Ensuite, en utilisant awk, je conserve le premier élément de la sortie, qui est le nom de fichier, ainsi que le 3e élément, qui est la résolution, sous la forme AxB.
identify InvertedIndex.jpg | awk '{print $1, $3}'
En sortie, on obtient
InvertedIndex.jpg 588x447
Je veux exécuter cette commande récursivement pour tous les sous-répertoires courants. Pour ce faire, find
permet de lister tous les fichiers. Le programme complet ressemble donc à ceci, prenant en entrée deux arguments:
- le répertoire
- le fichier de sortie
#!/bin/bash find "$1" -type f -exec identify \{\} \; | awk '{print $1, $3}' > "$2"
Identifier les fichiers à supprimer avec R
Pour la suite des choses, je vais utiliser le langage de programmation R, qui va me permettre de manipuler le fichier de sortie et de générer la liste des fichiers à supprimer
Je charge tidyverse
(parce que je suis un peu lâche et ça comprend tout, comme Hélix de Vidéotron 🙃)
library("tidyverse")
Ensuite, définition de mon répertoire et du fichier de sortie
my_dir <- "/something/something/" output_file <- "somefile.txt"
- Appel de mon programme bash écrit ci-haut avec la fonction system, j’utilise
paste0
pour construire la commande à exécuter:
system(paste0("bash liste_dimensions.sh ",my_dir," ",output_file))
- Positionner dans le répertoire de travail
setwd(my_dir)
- Lecture du fichier généré
files.txt <- read_table(paste0(my_dir,output_file), col_names = "nom")
- Séparation de mes deux colonnes
files.txt$nom %>% str_split_fixed(pattern = " ",n = 2) -> files_split
- Conversion en tibble
files_split %>% as.tibble() -> files_tibble
J’utilise ensuite separate
et transmute
pour obtenir 3 colonnes, une avec le nom de fichier, une avec la largeur et une avec la hauteur au format numérique
files_tibble %>% separate(col = V2, sep = "x", into = c("width","height")) %>% transmute( path=V1, width = width %>% as.numeric(), height = height %>% as.numeric(), ) -> files_attr
Je filtre ensuite les fichiers à supprimer
files_attr %>% filter(width <= 720 & height <= 720) -> to_delete
J’exporte la liste de fichiers à supprimer
to_delete$path %>% write_lines("to_delete.txt")
Supprimer les fichiers avec bash
De retour au terminal bash, je supprime les fichiers en utilisant xargs pour éviter un dépassement de capacité.
cat to_delete.txt | xargs -0 -I {} rm "{}"
Conclusion
Dans ce billet, j’ai montré comment faire le tri dans un répertoire de photos à l’aide d’un script qui permettra de sauver beaucoup de temps à un utilisateur averti.
Crédit photo
Image by S. Hermann & F. Richter from Pixabay