Shell script to open random jpegs with ImageMagick

2019-07-23 19:52发布

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

2条回答
淡お忘
2楼-- · 2019-07-23 20:11

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
查看更多
欢心
3楼-- · 2019-07-23 20:23

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
查看更多
登录 后发表回答