0

i have a folder of images with names foo<bar>.png where <bar> ranges from 0 to 100. When i create a gif of these images with

convert -dispose previous -delay 10 -resize 25% -loop 0 *.png myimage.gif

it creates a gif with images in order like 0,1,2,3...

Is there a command to select images in random order?

Seylim
  • 13
  • 2

2 Answers2

2

If your PNG images are all the same dimensions, and if the number of images can be evenly divided into a grid, like 72 images would make a grid of 8 x 9 images, and if your images are small enough to read them all into a single ImageMagick command, here is a command that will randomize the order of a group of 72 input images...

convert *.png -virtual-pixel tile +append -crop 9x1@ -append +repage ^
   -crop 1x9@ -distort affine "0,0 %[fx:floor(rand()*8)*(w/8)],0" -append +repage ^
   -crop 8x1@ -distort affine "0,0 0,%[fx:floor(rand()*9)*(h/9)]" +append +repage ^
   -crop 8x9@ +repage -set delay 10 -loop 0 image.gif

It basically makes a grid, randomly rolls all the rows, then randomly rolls all the columns. The shuffle scatters the images pretty well, but if you want a deeper shuffle, copy and paste those two "-crop ... -distort" lines, and add them below the first two...

convert *.png -virtual-pixel tile +append -crop 9x1@ -append +repage ^
   -crop 1x9@ -distort affine "0,0 %[fx:floor(rand()*8)*(w/8)],0" -append +repage ^
   -crop 8x1@ -distort affine "0,0 0,%[fx:floor(rand()*9)*(h/9)]" +append +repage ^
   -crop 1x9@ -distort affine "0,0 %[fx:floor(rand()*8)*(w/8)],0" -append +repage ^
   -crop 8x1@ -distort affine "0,0 0,%[fx:floor(rand()*9)*(h/9)]" +append +repage ^
   -crop 8x9@ +repage -set delay 10 -loop 0 image.gif

Carefully replace the "8"s and "9"s with the width and height of the grid that holds the number of images you're using. I use it in a script that shuffles a deck of playing card images, 13 rows and 4 columns.

This uses ImageMagick v6 in Windows CMD syntax. In a BAT script double all the percent signs "%%". It would probably work on a *nix OS by changing all the continued-line carets "^" to backslashes "\". For ImageMagick v7 use "magick" instead of "convert".

GeeMack
  • 4,486
  • 1
  • 7
  • 10
  • Very creative, nice work – Mark Setchell Oct 03 '21 at 07:34
  • This is definitely a creative way to do this but I feel like we should be able to find a more elegant way. I have tried it this way and it worked. But for future use I think the suggestion given by @MarkSetchell is somewhat nicer. Although I am facing problems there which you can see in the comments in his answer. – Seylim Oct 08 '21 at 17:56
1

I can tell you 2/3 of the answer on Windows, and hopefully some other kind soul can add the rest for you. Nobody said answers have to be complete.

  1. Create a text file containing the names of the PNGs you want to animate. I believe that is:

    DIR /B *.png > filelist.txt

  2. Shuffle the lines in that file. I don't know how to do that in Windows. In Linux and macOS it is shuf. Here's a little Python equivalent:

    python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," filelist.txt > shuffled.txt

  3. Pass that file to ImageMagick like this:

    convert -loop 0 -delay 80 @filelist.txt animation.gif


If you get that working, you can avoid the need for a temporary file by using this syntax:

DIR /B *.png | SHUFFLELINES | convert -loop 0 -delay 80 @- animation.gif
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Okay, thanks for this. I thought there might be a command directly in Imagemagick. – Seylim Oct 02 '21 at 23:17
  • There may be - if so, hopefully someone will tell us – Mark Setchell Oct 02 '21 at 23:20
  • 1
    See my solution below (or above?). – GeeMack Oct 03 '21 at 04:22
  • Okay, I have now successfully created a list in random order. When I use the command for Imagemagick as described above in step 3 I get an error because Windows PowerShell does not want me to use the @ operator. How do I pass the list to Imagemagick in Windows? – Seylim Oct 08 '21 at 17:53
  • Apparently the backtick is Powershell's escape... so try *"backtick"* followed by @ – Mark Setchell Oct 08 '21 at 17:55
  • It worked! It was the backtick `! I had tried percent, dollar and backslash but nothing worked. Thank you so much! – Seylim Oct 08 '21 at 18:04