I have a large batch of jpegs. I would like to write a shell script that selects 5 images randomly and then, using imageMagick, put them in a montage and then open this montage file. I would like this process to occur every 10 seconds.
I have tried this script
for f in *.jpg
do
shuf -ezn 5 * | xards -0 -n1 | montage *.jpg | display montage.jpg
done
but it is not working
It opens all of the images and gives me the following error message
image.sh 7: image.sh: Xards: not found
the go.sh script is kept in the same folder/directory as the images and now looks like this:
#!/bin/bash
# Get list of files into array - just once at start
files=(*.jpg)
# Do forever
first=0
while :; do
# Shuffle array
files=( $(shuf -e "${files[@]}") )
# Make montage of first 5 images in shuffled array
magick montage ${files[0]} ${files[1]} ${files[2]} ${files[3]} ${files[4]} montage.jpg
# Start displaying if first pass - leaving "display" running in background updating itself every second
if [ $first -eq 0 ] ; then
display -update 1 montage.jpg &
first=1
fi
# Snooze 10 and repeat
sleep 10
done
However that is returning
go.sh: 4: go.sh: Syntax error: "(" unexpected
However, when I run
bash go.sh
ImageMagick opens all images in the folder in one montage and I get the following error
go.sh: line 12: magick: command not found
Something like this:
#!/bin/bash
# Get list of files into array - just once at start
files=(*.jpg)
# Do forever
first=0
while :; do
# Shuffle array
files=( $(shuf -e "${files[@]}") )
# Make montage of first 5 images in shuffled array
magick montage ${files[0]} ${files[1]} ${files[2]} ${files[3]} ${files[4]} montage.jpg
# Start displaying if first pass - leaving "display" running in background updating itself every second
if [ $first -eq 0 ] ; then
display -update 1 montage.jpg &
first=1
fi
# Snooze 10 and repeat
sleep 10
done
Or this might be easier to understand:
#!/bin/bash
# Get list of files into array
files=(*.jpg)
montage=/tmp/montage.jpg
# Create initial "Loading sign"
convert -background black -fill white -pointsize 64 label:"Loading" $montage
display -update 1 $montage &
# Do forever
while :; do
# Shuffle array
files=( $(shuf -e "${files[@]}") )
# Make montage
magick montage ${files[0]} ${files[1]} ${files[2]} ${files[3]} ${files[4]} $montage
# Snooze 10 and repeat
sleep 10
done
Users of macOS may not have X11 support built into ImageMagick, they can install feh
using homebrew like this and also shuf
(actual command is gshuf
) from GNU coreutils:
brew install feh
brew install coreutils
and try the following version:
#!/bin/bash
# Get list of files into array
files=(*.jpg)
montage=/tmp/montage.jpg
# Create initial "Loading sign"
convert -background black -fill white -pointsize 64 label:"Loading" $montage
# Display "feh" running continuously in background passing the same image twice so we can cycle through the list!
feh --title "My Funky Montage" $montage $montage &
fehpid=$!
# Do forever
while :; do
# Shuffle array
files=( $(gshuf -e "${files[@]}") )
# Make montage
magick montage ${files[0]} ${files[1]} ${files[2]} ${files[3]} ${files[4]} $montage
# Cycle feh to next image
kill -s USR1 $fehpid
# Snooze 10 and repeat
sleep 10
done
Do you want to concat the images? In this case you could do something like:
while true; do
sleep 10;
montage -mode concatenate -tile 1x $(ls | sort -R | tail -n 5 | paste -sd " " -) montage.jpg && display montage.jpg;
done