imageimagemagick

How to add an image to all frames of a GIF using Imagemagick?


I would like to create a lightning effect for a photo using a lightning stock image and a personal photo. For example using the following lightning image:

enter image description here

I would like to put the panda below in all frames of the gif using Imagemagick:

enter image description here

I tried extracting all the frames using the command:

convert -coalesce lightning.gif out%05d.pgm

But I am stuck at how to do a batch composite operation for all frames. Would anyone know how to achieve this? I was hoping that there would be a single line solution using Imagemagick.


Solution

  • You are on the right track with -coalesce to separate the frames, I think the key ingredient in putting them back together is the MIFF (Magick Image File Format) which can be used to stream multiple images.

    So, here I stream all the individual, composited frames from inside a for loop into the final convert outside the loop to put them all back together:

    convert lightning.gif -coalesce frames-%03d.gif
    
    for f in frame*gif; do
       convert $f -gravity south \( panda.jpg -resize 50% \) \
          -compose colordodge -composite miff:-
    done | convert -delay 80 miff:-  anim.gif
    

    enter image description here

    In the first instance miff:- (miff<colon><hyphen>) means to use the "miff" format and output it to stdout. In the second it means to read it from stdin. For details, see section "STDIN, STDOUT, and file descriptors" in documentation page Command-line Processing.

    The selection of a decent blending mode is another issue!

    As a one-liner, that looks like this:

    for f in frame*gif; do convert $f -gravity south \( panda.jpg -resize 50% \) -compose colordodge -composite miff:- ; done | convert -delay 80 miff:-  anim.gif