Как найти все изображения с определенным размером пикселя с помощью командной строки?

16

Я пытаюсь найти все изображения JPG в папке с подпапками, которые имеют ширину или высоту ниже 300 пикселей.

Таким образом, я хочу обнаружить старые эскизы и удалить их.

Конечно, я могу найти все изображения, используя find:

find . -iname "*.jpg" -type f | ...

Но что следует за трубой? Какой пакет я могу использовать для определения атрибутов изображения?

mcbetz
источник

Ответы:

17

Вы можете использовать identifyиз imagemagick, и вы можете использовать следующую команду:

find . -iname "*.jpg" -type f -exec identify -format '%w %h %i' '{}' \; | awk '$1<300 || $2<300'

использование -exec <command> '{}' \;гарантирует, что ваше имя файла может содержать пробелы, в качестве альтернативы вы можете использовать

find . -iname "*.jpg" -type f | xargs -I{} identify -format '%w %h %i' {} | awk '$1<300 || $2<300'

где -I{}заботится о том же.

Что мне нравится в identifyтом, что вы можете указать формат вывода; в этом случае, '%w %h %i'который дает ширину, высоту и полный путь к изображению. Тогда awkвыражение сохраняет только те строки, для которых изображение меньше желаемого размера.

Пример вывода:

64 64 ./thumbsup.jpg
100 150 ./photomin.jpg

Редактировать: Если вы хотите только имена файлов (например, для трубопроводов rm), просто измените $lineв awkвыражении на $3, тогда будет напечатан только третий столбец.

Герхард Бургер
источник
3
Часть awk может быть сокращена: | awk '$1<300||$2<300'или | awk '$1<300||$2<300{print $3}'(когда нужен только 3-й столбец).
har-wradim
@ har-wradim Спасибо, хорошее предложение!
Герхард Бургер
7
Мне пришлось добавить новую строку ( '%w %h %i\n'), чтобы он работал на меня.
Qwr
Извините за запись в 6-летнем вопросе, но это единственный результат, который я нахожу в Google, который частично отвечает на мой вопрос, в основном я хочу найти изображения с определенными размерами или внутри них, а затем скопировать их в другой каталог. Я знаю, что cp используется для копирования, но мне не удается интегрировать эту команду с cp.
GhostOrder
@GhostOrder последует предложению @ har-wradim напечатать только 3-ю колонку, а затем добавить еще одну трубу с чем-то вроде этого| xargs -I {} mv {} /destination/directory/
Герхард Бургер
1

Я думаю, что принятый ответ очень хорош, но я хотел добавить другое возможное решение ...

Хотя сейчас я использую ImageMagickинструменты чаще всего сам, netpbmэто старый друг для обработки изображений. Вы можете увидеть размер любого формата изображения с помощью команды:

anytopnm file | pamfile

Это сгенерирует вывод, который выглядит следующим образом:

stdin:  PPM raw, 1650 by 1275  maxval 255

Чтобы ответить на вопрос «что следует за каналом?», Я использую while readчаще, чем использую, xargsпотому что он более гибкий. Мой netpbmответ на вопрос выглядит так:

find -iname \*.jpg | while read img; do \
  anytopnm "$img" | pamfile | \
    perl -ane 'exit 1 if $F[3]<300 || $F[5]<300' || rm -v "$img"; \
done
NateT
источник
1

Это сработало для меня:

find . -iname "*.png" -type f -exec identify -format '%i %wx%h\n' '{}' \; | grep '75x75'

Это выходной пример:

./2520161636481000.png 75x75

./2620160819191100.png 75x75

./2420181545550700.png 75x75

osroflo
источник
0

Команда identifyиз imagemagickпакета делает то, что вы хотите:

$ identify abc.jpg
abc.jpg JPEG 1952x3264 1952x3264+0+0 8-bit DirectClass 1.111MB 0.000u 0:00.000

Опять же, вам нужно будет затем использовать grepдля сортировки размера изображения.

Тем не менее, я подозреваю, что если у вас нет очень широкого диапазона размеров изображений, было бы проще просто findудалить файлы JPEG ниже заданного размера:

find -iname '*.jpg' -size -10k -delete

(Стоит запустить без -deleteпредварительной проверки, что он не найдет вещи, которые вы хотите сохранить - в противном случае он не будет запрашивать вас перед удалением).

chronitis
источник