Search code examples
linuxbashimagemagickxargsgnu-findutils

Unable to pass output of find to image magick


For some images in a directory as follows:

Atlas_21YearNova59_add_main.png
Atlas_21YearNova59_add_mask.png 
Atlas_Activity_2022faith52_add_main.png
Atlas_Activity_2022faith52_add_mask.png
Atlas_ActivityQA02_add_main.png
Atlas_ActivityQA02_add_mask.png

I need to multiply the main image with the mask image as

magick Atlas_ActivityQA002_add_main.png Atlas_ActivityQA002_add_mask.png -compose multiply -composite 002.png

to do this for every image:

for i in `seq -w 1 100`
do 
    find -regextype sed -regex ".*"$i".*" | xargs -I {} magick {} -compose multiply -composite $i".png"
done

However instead of passing the main and mask image together, they are passed one by one. Using -t flag in xargs, the command being executed is

magick ./Atlas_ActivityQA002_add_main.png -compose multiply -composite 002.png 

The output of

for i in `seq -w 1 10`
do 
    find . -regextype sed -regex ".*"$i".*" | xargs
done

is

./Atlas_21YearNova59_add_main.png ./Atlas_21YearNova59_add_mask.png  
./Atlas_ActivityQA02_add_main.png ./Atlas_ActivityQA02_add_mask.png

But the images are passed separtely when called with magick. How to fix this?


Solution

  • Ok, so you shifted the goal posts since the images are no longer a sequence, but still you just have to extract the "root name", which can be done easily in bash:

    for f in *_main.png
    do
        rootname=${f%%_main.png}
        magick ${rootname}_main.png ${rootname}_mask.png -compose multiply -composite ${rootname}.png
    done
    

    If you are using ksh, you can also extract the root name using the basename command:

    for f in *_main.png
    do
        rootname=$(basename $f _main.png)
        magick ${rootname}_main.png ${rootname}_mask.png -compose multiply -composite ${rootname}.png
    done
    

    In bash if you have multiple folders, you can still process all the files in one shot with:

    # enable '**' matching
    shopt -s globstar  
    # All *_main.png in all directories below the current one
    for f in **/*_main.png 
    do
        # this keeps the directory
        rootname=${f%%_main.png}  
        # All files have a directory specification
        magick ${rootname}_main.png ${rootname}_mask.png -compose multiply -composite ${rootname}.png 
    done