Ausgabe der Montage automatisch anhand von Eingabedateien benennen

696
Morgan

Ich habe einen Ordner mit Bildern, die in Kanäle unterteilt sind:

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 

Was ich jetzt mache, macht 4x1 Bilder mit Montage und Benennung, dann "OUTPUT_% d.jpg". Dies zwingt mich jedoch dazu, sie manuell in zB "IMAGE_A.jpg" umzubenennen, was für diese große Bildersammlung sehr zeitaufwändig ist.

Was ich gerne machen würde, ist, aus der Liste oben automatisch 4x1-Montagen mit dem folgenden Namen zu erstellen:

IMAGE_A.jpg IMAGE_A1.jpg IMAGE_B.jpg 

Im Idealfall möchte ich alle "IMAGE_A" automatisch zu einer 4x-Montage, alle "IMAGE_B" zu einer anderen zusammenfügen und so weiter. Jeder IMAGE_ [Buchstabe] kann aus 1 bis 4 Zahlen bestehen, so dass Sie nicht einfach eine 4x2-Montage erstellen können.

Ich habe versucht,% [Name] und% f ohne Erfolg zu verwenden, und habe nichts hilfreiches im ImageMagick-Handbuch oder in meinen Google-Suchen gefunden.

Ich vermute, dass ich dazu ein BASH-Skript verwenden muss, aber ich fürchte, ich habe zu wenig Wissen, um dies ohne Hilfe zu tun.

Vielen Dank im Voraus für jede Hilfe!

0

1 Antwort auf die Frage

1
terdon

Sammeln Sie zuerst die Liste der Bildnamen:

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

Nun führe sie durch montage:

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

Dies setzt voraus, dass Ihre Dateinamen keine Leerzeichen oder andere merkwürdige Zeichen enthalten. Ich bin mir nicht sicher über Ihren "idealen" Fall. Wenn Sie Ihre Frage aktualisieren, um Ihre "ideale" Ausgabe anzuzeigen, sollte ich in der Lage sein, etwas für Sie herauszufinden.


Aktualisieren:

Ich habe ein kleines Perl-Skript geschrieben, das tun soll, was Sie brauchen:

#!/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` } 

Sie können es entweder als foo.ploder was auch immer Sie möchten speichern und so ausführen:

ls *jpg | perl foo.pl 

Oder Sie können es als One Liner betreiben:

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`;}' 

WICHTIG : Dieses Skript ist sehr einfach und funktioniert nicht, wenn Ihre Dateinamen Leerzeichen oder andere merkwürdige Zeichen enthalten. Ich gehe davon aus, dass dies kein Problem für Sie ist, es ist relativ einfach zu beheben, macht die Syntax jedoch umständlicher.

The ideal case would be: Files are named `[name]-[letter][number]-[channel].jpg`, where `[number]` isn't present on all images (the letter-only image being an overview). Ideally all images with the same `[name]` and `[letter]` should be in the same montage, each image labeled with `[channel]`, the montage having a header being `[name]` and the file named `[name]-[letter].jpg` Morgan vor 11 Jahren 0
Nach allem, was ich sehen kann, sieht der Befehl, den Sie geschrieben haben, nur an der [[Buchstabe] [Zahl] `- Endung. Da für alle `[Name]` die gleichen sind, funktioniert das nicht perfekt. Bei Bedarf könnte ich die Benennung der Dateien leicht ändern, so dass alle `[Nummer]` haben. Morgan vor 11 Jahren 0
Thanks to your script above, with slight modifications, I managed to almost do what I want: `ls *jpg | gawk -F_ '' | sort | uniq | while read n; do montage $n\_* -title $n -tile 4x $n.jpg; done;` However, I can't figure out how to separate them based on only the letter (see above). Nor can I figure out how to fetch the channel name. Now, this is of lesser importance - and while I'd love to know how to do this - you've already helped me enough. **Thanks!** Morgan vor 11 Jahren 0
@Morgan du bist sehr willkommen, mir ist immer noch nicht ganz klar was du willst. Könnten Sie ein detailliertes Beispiel geben? Möchten Sie alle Bilder von `A`,` A1`, `A2` usw. in derselben Datei speichern? Einige einfache Skripte sollten in der Lage sein, das zu tun, was Sie brauchen. Auch das `ls * jpg` in Ihrem vorherigen Kommentar ist nutzlos, wenn Sie auch` ls * HeLa * `tun. terdon vor 11 Jahren 0
Genau das "A #" sollte sich in derselben Montage befinden, das "B #" sollte sich in der gleichen Montage befinden und so weiter. Was ich brauche, ist, alle Bilder, die denselben Namen haben, zum Beispiel "NAME-A #", aufzunehmen und eine Montage davon zu machen, genauso wie für "NAME-B #" und so weiter. Am nächsten habe ich `gawk -F_ '` `` gemacht, aber ich weiß nicht, wie ich die Nummer loswerden kann. Da einige der Dateien mehr _ enthalten, frage ich mich auch, ob es möglich ist, die Zählung von hinten durchzuführen, da die Nummern A, B usw. immer vor _ (CHANNEL) stehen. Morgan vor 11 Jahren 0
@Morgan siehe aktualisierte Antwort, das Skript sollte für Sie funktionieren. terdon vor 11 Jahren 0