Home > Blockchain >  How to execute imagemagick with a string as input for filenames - in bash
How to execute imagemagick with a string as input for filenames - in bash

Time:11-04

I am trying to write a code to do the below.

1: Get all the directory names from input line into a string (Number of directory inputs could vary)

2: For all the tiff files in those directories montage the images (using imagemagick) with the same names and save it in the main folder or given folder.

I want to combine two or more images (depending on the number of directories in the command line input). Each directory has image outputs with same name to the other directory. I wanna combine files with the same names from given directories

The code I wrote is below but its not passing $name as variable to montage command. What am I doing wrong here? Any help would be greatly appreciated.

for arg in "$@"; do # 
n1=$arg
fname =$n1"\${name} " #Get all the directory names in a string with $name at the end. for eg: Baseline/$name
done
echo $fname

for n in $arg/*.tif; do
name="$(basename "$n")"
name1=$(echo "$name" | cut -f 1 -d '.')
montage -tile 3x3 $fname name1.png
exit
done

More DetailsExample

CodePudding user response:

Updated Answer

Thank you for the clarification, you can do what you want if you save the following as monty.sh and make it executable with:

chmod  x monty.sh

Here's the code:

#!/bin/bash

# Goto first subdirectory and take it off args list
cd "$1"
shift

# Grab remaining directory names into array
friends=( "$@" )
>$2 echo "DEBUG: friends=${friends[@]}" 

# Iterate over files in first directory
for this in *.tiff ; do
   >&2 echo "DEBUG: this=$this"
   # Generate list of files to montage
   { 
      # ... starting with this one...
      echo "$this"
      # ... and adding in his friends
      for friend in "${friends[@]}" ; do
         next="../${friend}/${this}"
         >&2 echo "DEBUG: next=$next"
         if [ -f "$next" ] ; then
             echo "$next"
         else
             >&2 echo "ERROR: file $next is missing"
         fi
      done
    } | magick montage -tile 3x @- ../"${this/tiff/png}"
done

Then your command will be:

./monty.sh Output1 Output2 Output3

or, more succinctly:

./monty.sh Output{1,2,3}

In case you are unfamiliar with bash syntax, the code in the middle of the for loop is essentially doing:

...
...
{ 
   echo first filename to montage onto stdout
   echo second filename to montage onto stdout
   echo third filename to montage onto stdout
} | magick montage <ALL FILENAMES ON STDIN> result.png

So it is important that all error messages inside {...} are sent to stderr else the error messages will go to the montage command which will interpret them as filenames. That's why all the debug statements start with >&2 echo ... because that directs them to stderr so they don't get mixed up with stdout.


Original Answer

I don't understand what you are trying to do, but if you can write all the filenames into ImageMagick's stdin, you can make it montage them like this:

find . -name "*.tif" -print | magick montage -geometry  0 0 -tile x3 @- result.png
  • Related