2

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
heroZero
  • 173
  • 3
  • 18

2 Answers2

1

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
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • wow, thanks, I have tried both scriptes but returning image.sh: 4: image.sh Syntax error: "(" unexpected.Also, using raspberry pi/linux but will be hoping to get it work on my mac – heroZero Jun 07 '19 at 13:44
  • I don't understand your error message. You need to copy the above code and paste it into a file called `go` in your HOME directory. Then make it executable with `chmod +x $HOME/go` Then you can run it with `$HOME/go` If it doesn't work, change the first line to `#!/bin/bash -x` and run it again for debug and paste the result into your original question please - by clicking `edit` under your question. Thanks. – Mark Setchell Jun 07 '19 at 13:50
  • Are you using Ubuntu where `bash` is not actually `bash` but `ash`? – Mark Setchell Jun 07 '19 at 14:17
  • 1
    Or have you got some lines before the shebang? The **very first** line of the file must be `#!/bin/bash` or `#!/usr/bin/env bash` – Mark Setchell Jun 07 '19 at 14:19
  • Just triple checked, first line is #!/bin/bash – heroZero Jun 07 '19 at 14:23
  • 1
    What precise command do you use to start it with please? It is specifically a `bash` script and it needs to run in a `bash` shell because it uses a `bash` array on line 4. It cannot run under `sh`. – Mark Setchell Jun 07 '19 at 14:26
  • ah, ok from terminal: sh go.sh – heroZero Jun 07 '19 at 14:30
  • 1
    Try `bash go.sh` ! – Mark Setchell Jun 07 '19 at 14:35
  • That runs it but I have edited OP to show new error – heroZero Jun 07 '19 at 14:40
  • 1
    Ok, you have an old version of ImageMagick. Just remove the word `magick` so that the command on line 12 says `montage ...other stuff ...` – Mark Setchell Jun 07 '19 at 14:57
  • Excellent! Good luck with your project and come back if you get stuck - questions (and answers) are free :-) – Mark Setchell Jun 10 '19 at 07:56
  • I will Mark..actually as a relevant newbie here, if I have questions related to the project, should I post a new question or reedit my original post? – heroZero Jun 10 '19 at 07:57
  • 1
    Edited and re-edited questions are a bit of a pain as they ramble and go *off focus*. I would suggest you post a new one and add a link back to the old one for reference - as I said *"Questions are free"*. You can get a link by clicking the `share` button under your question and copying the URL in the pop-up box. – Mark Setchell Jun 10 '19 at 08:04
  • You can also add a comment under this original question linking to the new question, and in fact, if you do that, all the folks who answered/commented on the original question will be receive a notification of the comment and be directed to the new question, so you will be even more likely to get an answer from me, or anyone interested in the original question :-) In essence, I am suggesting to link backwards and forwards. – Mark Setchell Jun 10 '19 at 08:11
  • 1
    Ah brilliant, I suspect I will have driven you all crazy in no time ;) * * I will of course try to figure out 'stuff' before asking ! – heroZero Jun 10 '19 at 08:14
  • Well that didn't take long https://stackoverflow.com/questions/56524759/projecting-random-images-montages – heroZero Jun 10 '19 at 10:38
0

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
Gabe
  • 34
  • 2