2

I'm creating an animated gif using mogrify's convert. However, at the moment I run in on a folder with dozens of images in it, and I just instruct it to use all of the images it finds. However, I'd like it to only use files that were created on a particular date. Can I do such a thing?

Current command used:

convert -delay 10 -loop 0 images/* animation.gif

All my filenames are timestamps so alternatively I'd like to be able to specify a range, something like:

convert -delay 10 -loop 0 --start="images/147615000.jpg" --end="images/1476162527.jpg" animation.gif

I've tried the convert man pages but no luck. Is any of this possible?

  • just to keep the next person from getting thrown off, I suspect your "images/147615000.jpg" was missing a zero at the end, to make it closer in epoch-seconds to 1476162527. – Jeff Schaller Oct 11 '16 at 8:54
1

This small shell script will loop through every file in the current directory and compare it's last-modified timestamp to the range that is built by the start and end timestamps (here, October 10th). Matching files are added into the files array, and if there are any files in the array, it calls convert on them. Adjust the -gt 0 to -gt 1 if you want to have at least two files (or more).

Note that the creation time is not usually preserved in a file's (Unix) attributes, so this method could be fooled by a simple touch 1476158400.jpg, which would make an old file appear new. See below for a second option.

#!/usr/bin/env bash

start=$(date +%s -d 'Oct 10 2016')
end=$(date +%s -d 'Oct 11 2016')

files=()
for f in *
do
  d=$(stat -c%Z "$f")
  [[ $d -ge $start ]] && [[ $d -le $end ]] && files+=("$f")
done

[[ ${#files[*]} -gt 0 ]] && convert -delay 10 -loop 0 "${files[*]}" animation.gif

Alternatively, if the filenames themselves encode the creation timestamp, then you could use a brute-force loop to find them:

start=$(date +%s -d 'Oct 10 2016')
end=$(date +%s -d 'Oct 11 2016')
files=()
for((i=start;i<=end;i++)); do [[ -f "${i}.jpg" ]] && files+=("${i}.jpg"); done
[[ ${#files[*]} -gt 0 ]] && convert -delay 10 -loop 0 "${files[*]}" animation.gif
  • Both of these methods assume you have a GNU-ish date utility that accepts the -d option; the first solution also relies on the GNU stat utility. Both options rely on a shell that supports arrays. – Jeff Schaller Oct 11 '16 at 8:56
1

If your images where named slightly differently, like so:

images/147615000-000.jpg
images/147615000-001.jpg
... more images ...
images/147615000-090.jpg

You could then do this:

convert -delay 10 -loop 0 images/147615000-*.jpg animation.gif

But I'm guessing the images are a timestamp for a reason.

You could try something like this script:

#!/bin/sh
# 
# Find images from $1 to $2 inclusive

if [ "$2" = "" ]
then
    echo "Pass the first and last file."
    exit
fi
# Basic file check
if [ ! -f "$1" ]
then
    echo "$1 not found."
    exit
fi
if [ ! -f "$2" ]
then
    echo "$2 not found."
    exit
fi

# Get the file list. Note: This will skip the first file.
list=`find "./" -type f -newer "${1}" -and -type f -not -newer "${2}"`

# Include the first image
list="./$1
$list"
# Sort the images as find may have them in any order
list=`echo "$list" | sort`

# create the animation.gif
convert -delay 10 -loop 0 $list animation.gif

# say something
echo "Done"

Place that script in the directory you want to create "animation.gif" and I'm assuming the images are in a sub-directory. You would call like so:

sh ./fromToAnimation.sh images/147615000.jpg images/1476162527.jpg

This will work so long as there are no spaces or other special characters in the file names or path.

  • Why not xargs together with find if you are going to include it on the commandline anyway? The interesting case is if the list is too long for the commandline ... – dirkt Oct 11 '16 at 8:05
  • @dirkt You should post your answer. The command line limit on a modern Linux is often near 2MB, but yes, this could be an issue. I could not thing of a another cleaner way without more info from the OP. – Tigger Oct 11 '16 at 8:38
  • Thanks. I accepted the other one because it does not require me to figure out which timestamp corresponds to which date (I can just state which date I want the images for), which makes it a bit more convenient. But thanks for the script! – please delete me Oct 13 '16 at 14:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.