web-dev-qa-db-fra.com

Rechercher des images dans un répertoire Linux en fonction de leur résolution

Je souhaite numériser toutes les images d'un répertoire (de manière récursive dans des sous-dossiers) et trouver celles dont la résolution est supérieure à un seuil spécifique (par exemple, celles dont la résolution est au moins 800x600 ou si elles sont plus faciles, disons avec une largeur supérieure à 1000 pixels). Ensuite, j'aimerais enregistrer leur adresse dans un fichier texte, accompagnant leur résolution (ou [width], [height] pour une meilleure mise en forme).

Donc, log.txt ressemblerait à ceci:

/home/users/myuser/test/image1.jpg, 1800, 1600
/home/users/myuser/test/image20.jpg, 2800, 2600
/home/users/myuser/test/image30.jpg, 1500, 1200

Comment puis-je faire cela en utilisant un script bash? Je dois numériser des millions d'images.

7
Tina J

Via bash récursif glob et la commande identifyde ImageMagick:

shopt -s globstar
identify -format "%f, %w, %h\n" **/*.{png,jpg,jpeg}

Enregistrer cette sortie dans un fichier consiste simplement à ajouter > mylog.txt à la commande précédente, c'est-à-dire

identify -format "%f, %w, %h\n" **/*.{png,jpg,jpeg} > mylog.txt

À partir de là, vous pouvez utiliser awkou Perlpour comparer les colonnes mylog.txt.

awk -F ',' '$2 > 800 && $3 > 600' mylog.txt

awkutilise ici , comme séparateur pour les colonnes et la structure habituelle pour awkest /PATTERN/{COMMANDS}, la valeur par défaut étant simplement l'impression si {COMMANDS} est omis; dans l'exemple ci-dessus, si le modèle $2 > 800 && $3 > 600 est vrai, c'est-à-dire si l'image correspond à la résolution souhaitée, vous l'aurez imprimé à l'écran.

Et probablement, en sautant l’étape de log entre les deux, il serait un peu mieux de tout canaliser:

shopt -s globstar
identify -format "%f, %w, %h\n" **/*.{png,jpg,jpeg} | awk -F ',' '$2 > 800 && $3 > 600' > filtered_images.txt

Si vous rencontrez une erreur arguments list too long, la commande findest généralement la meilleure approche pour parcourir de manière récursive l'arborescence de répertoires. identifypeut être appelé à l'aide de l'indicateur -exec de findname __ et le filtrage peut toujours être géré par awkname__:

$ find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -exec identify -format "%f, %w, %h\n" {} \; | awk -F ',' '$2 > 800 && $3 > 600' 
fanart.jpg, 1920, 1080
fanart.jpg, 1920, 1080
globalsearch-background.jpg, 1920, 1080
fanart.jpg, 1280, 720

Comme d'habitude, n'oubliez pas d'ajouter > log2.txt pour tout enregistrer dans un fichier.

Le chemin complet du fichier peut être traité de deux manières. Premièrement, en spécifiant %d/%f dans la chaîne de format de la commande identifyou utilisez l'option findname__'s -printf. C'est soit

find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -exec identify -format "%d/%f, %w, %h\n" {} \; | awk -F ',' '$2 > 800 && $3 > 600'

Ou

find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -printf "%p, " -exec identify -format "%w, %h\n" {} \; | awk -F ',' '$2 > 800 && $3 > 600'
7