Whilst sorting some photos I remembered I had taken a sequence of photographs at different stages of the build of various lego sets (including this one - Great Pyramid of Giza). This was an opportunity to put them together into some kind of animation showing the build progressing.
[note: I did not take the pictures with this aim in mind, if I had then I would not have run into some of the issues I had, better subject positioning, better backgrounds, consistent camera angle etc.]
I knew I could use ImageMagick to bring together my "static" images into an animation but never done this for a significant number of photos.
[note: I could also have done something with ffmpeg - perhaps a future project]
My original requirement was to extract the data and time the picture was taken from the exif data and display that on the image. As I started to look at this I noticed a common positioning and colour might not work due to the various backgrounds and positioning of the subject (again better planning when taking the images would have helped).
I also saw mention of a "polaroid" option in ImageMagick which would add a frame similar in style to a polaroid picture and would also put the image on a jaunty angle. These "polaroids" could then be stacked to make an interesting animation.
Below is my testing on one set of photos (Lego Pyramid), I am hoping to then take a minimal set of steps and apply it to other groups of photos.
Adding a Polaroid effect and adding the Date and Time the photo was taken from the exif data:
Image looked quite good with the Polaroid frame but the text was way too small to be readable (more on why later).
I also wanted the manipulation to be as automatic as possible so I could apply the same to other project photos, so I run the commands through a loop in bash.
Bash loop (increased font size - still not big enough)
[side note - separate article on image orientation]
It was obvious when looking at the resulting test images that the images were both too large (did not do any scaling of the originals) and that the orientation was wrong. This is not always obvious when looking at the photos in modern tools that do auto-orientation. As the orientation of the original images was what I wanted when viewed in the image viewer I was using, I decided to manually adjust the few images that were not as I wanted.
I now had a directory of original images and some additional "fixed" images, for my processing I would only want the "fixed" image (if available) and the originals if not. For following examples/tests I also decided to write the images to new directories so it would be easy to role back to a previous step/set of transformations.
Another quick bash loop, and some bash variable manipulation:
if [ -e "$fix" ] ; then echo "fix exists!" ; img=$fix ; echo "using $img" ;fi; \
magick -caption %[exif:DateTimeOriginal] "$img" -gravity center -background black -pointsize 25 +polaroid polaroids/"polaroid""$img"; \
done
Orientation of images is now how I want but still too large and caption font size too small.
As I could get roughly the effect I wanted for each of the images I decided to go back and scale down the images to something more managable and not the files directly from the camera (yes I should have done this first but initially I wanted as little manipulation as possible and to see if I could get something to work).
Doing a few tests I went with 15% of the original in the end, which is about 600x450 pixels for the images that did not need rotation.
Added the polaroid effect to the scaled images and because the images I am using are much smaller then the pointsize used gives a reasonable size for the caption without needing to increase it. Win!
Lets test creating the animation with following command:
Explanation of options used, start with a Black background 500x500 pixels (for those keeping count that is too small for the 15% scaled images I mentioned earlier, this test was done with images at 10% scaled images) and "do nothing" as the disposal for this first transition (I added this as I wanted to test different options for each frame as I add the images). Overlay each image every 5 seconds (5, 1 second ticks) and set the disposal to previous (return canvas back to how it looked like before applying the image).
There were some problems with this, I wanted a stacking look so previous disposal option is probably not what I want, and the polaroid effect was adding some extra colouring round the edge (probably want this to be transparent). The images that were originally rotated were bigger than the canvas size I was using and so were partly out of view and caused the images to overlay in a way that made the stacking effect look odd.
I also noticed that even if I got a stacking effect when viewing the resulting gif animation (which should not have happened with the dispoal setting I was orginally testing above) this was being caused by overflow of the buffer the image viewer was using to display the images and therefore was not clearing the previous image as requested.
As mentioned at the top if I was planning to animate the images from the beginning I would have set the Photos up better, subject in the middle of the frame and all take with the same orientation etc.
At this point I decided the simplest solution is to crop the rotated images, I don't need the uncropped rotation so I just overwrote them. I also decided to go with a slightly large image so only scaled to 15% instead of 10% that I had originally been testing.
The majority of the images were 600x400 pixels and the rotated ones (which were causing me the issue were 450x600 pixels) so I decided to crop them using:
Applied the polaroid effect again to these cropped images.
Nearly there, but something looked odd, there were extra artifacts which looked like background bleeding through from a previous image
At this point I thought it would be best to have a transparent background to make sure this was not happening, to achieve this I probably need to work with pngs instead of jpegs so I converted them all using:
Interesting note:
I was not aware there was such a thing as animated png (APNG), so I tried this to generate one from my images using:
This did not work very welli, some issues with backgrounds and transitions, also support did not appear to be there in the image viewers I tried and it was only displaying the first image. I might come back and look at this in the future.
Animated gif generated using the following command:
Not quite what I wanted as I had forgotten to change the disposal setting as it originally seemed to work in the image viewer as mentioned above, I actually wanted "-dispose none" so command should be:
After all this here is the resulting animated gif for my Lego Pyramid build
Animation gets a little mangled when uploaded but gives you an idea.