Автоматически присваивать имя выводу монтажа на основе входных файлов

709
Morgan

У меня есть папка с изображениями, разделенными на каналы:

IMAGE_A_R.jpg IMAGE_A_G.jpg IMAGE_A_B.jpg IMAGE_A_RGB.jpg IMAGE_A1_R.jpg IMAGE_A1_G.jpg IMAGE_A1_B.jpg IMAGE_A1_RGB.jpg IMAGE_B_R.jpg IMAGE_B_G.jpg IMAGE_B_B.jpg IMAGE_B_RGB.jpg 

Сейчас я делаю снимки 4х1 с использованием монтажа и именования, затем "OUTPUT_% d.jpg". Это, однако, вынуждает меня вручную переименовать их, например, в «IMAGE_A.jpg», что для этой большой коллекции изображений занимает очень много времени.

Что я хотел бы сделать, так это автоматически из списка выше создать монтаж 4x1 с именем:

IMAGE_A.jpg IMAGE_A1.jpg IMAGE_B.jpg 

В идеале, я хотел бы автоматически объединить все IMAGE_A в 4x монтаж, все IMAGE_B в другой и так далее. Каждое IMAGE_ [буква] может иметь от 1 до 4 цифр, поэтому невозможно просто сделать, например, монтаж 4х2.

Я безуспешно пытался использовать% [name] и% f и не нашел ничего полезного ни в руководстве ImageMagick, ни в своих поисках в Google.

Я подозреваю, что для этого мне понадобится какой-нибудь BASH-скрипт, но я боюсь, что у меня мало знаний, чтобы сделать это без посторонней помощи.

Заранее благодарю за любую помощь!

0

1 ответ на вопрос

1
terdon

Сначала соберите список имен изображений:

ls *jpg | gawk -F_ '' | sort | uniq 

Теперь пропустите их через montage:

ls *jpg | gawk -F_ '' | sort | uniq |  while read n; do montage *\_$n\_* IMAGE_$n.jpg; done 

Это предполагает, что ваши имена файлов не содержат пробелов или других странных символов. Я не уверен в вашем "идеальном" случае. Если вы обновите свой вопрос, чтобы показать свой «идеальный» результат, я смогу кое-что для вас решить.


Обновить:

Это я написал крошечный Perl-скрипт, который должен делать то, что вам нужно:

#!/usr/bin/env perl  my %k; ## declare the hash that will store the image names while(<>){ ## loop through STDIN chomp; ## remove newline (\n) @a=split(/_/); ## split the line on '_' and save as array @a  ################################################### # Since the image names can have varying numbers # # of "_", we want to use the penultimate item in # # the array ($a[$#a-1]) as the image name prefix # ################################################### $a[$#a-1]=~s/\d*//g;  ############################################################# # Now that we have the prefix ('A' or 'B' in your example), # # we will save this image name in the hash of that prefix # ############################################################# $k{$a[$#a-1]}{$_}=1; } ## The keys of the hash '%k' are all the prefixes we have found foreach my $prefix (keys(%k)){ @images=keys(%{$k{$prefix}}); ## all the images with this prefix  ## Print the montage command to be executed (testing) print "montage @images -title $prefix -tile 4x $prefix.jpg\n";  ############################################################## # If the commands printed above are correct, uncomment this # # line to execute them instead of only printing. # ############################################################## #`montage @images -title $prefix -tile 4x $prefix.jpg` } 

Вы можете либо сохранить его как foo.plугодно, либо запустить его так:

ls *jpg | perl foo.pl 

Или вы можете запустить его как один лайнер:

ls *jpg | perl -e 'my %k; while(<>){$_}=1;} foreach my $prefix (keys(%k)){@images=keys(%{$k{$prefix}}); `montage @images -title $prefix -tile 4x $prefix.jpg`;}' 

ВАЖНО : Этот скрипт очень прост и не будет работать, если ваши имена файлов содержат пробелы или другие странные символы. Я предполагаю, что это не проблема для вас, это относительно легко исправить, но делает синтаксис более сложным вокруг.

В идеальном случае файлы будут называться `[name] - [letter] [number] - [channel] .jpg`, где` [number] `присутствует не на всех изображениях (изображение, состоящее только из букв, является обзором ). В идеале все изображения с одинаковыми `[name]` и `[letter]` должны быть в одном и том же монтаже, каждое изображение помечено как `[channel]`, причем монтаж имеет заголовок `[name]` и файл с именем ` [имя] - [письмо] .jpg` Morgan 11 лет назад 0
Из того, что я вижу, команда, которую вы отправили, смотрит только на окончание `[letter] [number]`. Так как одинаковы для всех `[name]`, это не будет работать идеально. При необходимости я мог бы легко поменять имена файлов, чтобы у всех было `[число]`. Morgan 11 лет назад 0
Благодаря вышеприведенному сценарию, с небольшими изменениями, мне удалось сделать почти то, что я хочу: `ls * jpg | gawk -F_ '' | сортировать | uniq | пока читаешь; сделать монтаж $ n \ _ * -титла $ n -тиля 4x $ n.jpg; done; `Однако я не могу понять, как разделить их на основе только буквы (см. выше). Также я не могу понять, как получить название канала. Теперь, это имеет меньшее значение - и хотя я хотел бы знать, как это сделать, - вы уже достаточно мне помогли. **Спасибо!** Morgan 11 лет назад 0
@ Морган, пожалуйста, я все еще не совсем понимаю, чего ты хочешь. Не могли бы вы привести подробный пример? Вы хотите, чтобы все изображения `A`,` A1`, `A2` и т. Д. Находились в одном файле? Некоторые простые сценарии должны быть в состоянии сделать то, что вам нужно. Кроме того, `ls * jpg` в вашем предыдущем комментарии бесполезен, если вы также делаете` ls * HeLa * `. terdon 11 лет назад 0
Точно все `A #` должны быть в одном и том же монтаже, все `B #` должны быть в одном и том же и так далее. Мне нужно взять все изображения с одинаковыми именами, например, `NAME-A #`, и сделать их монтаж, то же самое для `NAME-B #` и так далее. Самое близкое, что я могу сделать, это сделать `gawk -F_ '`, но я не знаю, как избавиться от числа. Поскольку в некоторых файлах содержится больше `_`, мне также интересно, возможно ли выполнить подсчет сзади, поскольку` A # `,` B # `и т. Д. Всегда идут перед` _ [CHANNEL] `. Morgan 11 лет назад 0
@Morgan смотри обновленный ответ, скрипт должен работать на тебя. terdon 11 лет назад 0

Похожие вопросы