-
Some tools for animated gifs
06/11/2015
Source(latest update : 2015-11-06 15:01:11)
It took me some time to find how to merge two animated gifs (using freeware only, as usual). So it is worth sharing my notes. Below are the two animated gifs used for my example.
Append one gif to the other
Below these are the same animations but they are merged into only one single animated gif, by appending the second one at the right to the first one.
The ImageMagick command I used to create it (found on imagemagick.org) is the following one:
convert file1.gif'[0]' -coalesce \\( file2.gif'[0]' -coalesce \\) \\ +append -channel A -evaluate set 0 +channel \\ file1.gif -coalesce -delete 0 \\ null: \\( file2.gif -coalesce \\) \\ -gravity East -layers Composite output.gif
To append vertically, run:
convert file1.gif'[0]' -coalesce \\( file2.gif'[0]' -coalesce \\) \\ -append -channel A -evaluate set 0 +channel \\ file1.gif -coalesce -delete 0 \\ null: \\( file2.gif -coalesce \\) \\ -gravity South -layers Composite output.gif
and you will get this single animation:
Join one gif after the other one
One can also join the two animations, the second one after the other one, including a delay between them (4 seconds in the example below):
convert file1.gif -coalesce \ \( +clone -set delay 4/1 \) +swap +delete \ \( file2.gif -coalesce \) \ \( +clone -set delay 4/1 \) +swap +delete \ -resize 400x300 -layers optimize output.gif
Compress a gif
Finally I discovered gifsicle while I was searching a way to compress an animated gif. It achieves an amazing performance, by simply running this line:
gifsicle -O3 --colors 256 < infile.gif > outfile.gif
To know more about gifsicle (which not only serves to compress), take also a look at this post on graphicdesign.stackexchange.
R functions
Obviously, the previous command lines are not user-friendly. I wrote some R functions to run them more conveniently (at least, for R users). Moreover, since I usually use the animation package to create my animations, these functions provide additional tools. Here are two examples of my functions, they should be enough to understand how to use them:
gif_append("file1.gif", "file2.gif", "outfile.gif", horizontal=FALSE, extra.opts="-resize 300x400") gif_append("file1.gif", "file2.gif", "outfile.gif", delay=4) gif_compress("file.gif", "outfile.gif", extra.opts="--colors 256"))
And their code is given below:
gif_append <- function(gif1, gif2, outgif, horizontal=TRUE, show=TRUE, extra.opts=""){ command <- ifelse(horizontal, sprintf("convert %s'[0]' -coalesce \\( %s'[0]' -coalesce \\) \\ +append -channel A -evaluate set 0 +channel \\ %s -coalesce -delete 0 \\ null: \\( %s -coalesce \\) \\ %s -gravity East -layers Composite %s", gif1, gif2, gif1, gif2, extra.opts, outgif), sprintf("convert %s'[0]' -coalesce \\( %s'[0]' -coalesce \\) \\ -append -channel A -evaluate set 0 +channel \\ %s -coalesce -delete 0 \\ null: \\( %s -coalesce \\) \\ %s -gravity South -layers Composite %s", gif1, gif2, gif1, gif2, extra.opts, outgif)) system.fun <- if (.Platform$OS.type == "windows") shell else system if(show) message("Executing: ", strwrap(command, exdent = 2, prefix = "\n")) system.fun(ifelse(.Platform$OS.type == "windows", sprintf("\"%s\"", shQuote(command)), command)) }
gif_join <- function(gif1, gif2, outgif, delay=3, show=TRUE, extra.opts=""){ command <- sprintf("convert %s -coalesce \\ \\( +clone -set delay %s/1 \\) +swap +delete \\ \\( %s -coalesce \\) \\ \\( +clone -set delay %s/1 \\) +swap +delete \\ %s -layers optimize %s", gif1, delay, gif2, delay, extra.opts, outgif) system.fun <- if (.Platform$OS.type == "windows") shell else system if(show) message("Executing: ", strwrap(command, exdent = 2, prefix = "\n")) system.fun(ifelse(.Platform$OS.type == "windows", sprintf("\"%s\"", shQuote(command)), command)) }
gif_compress <- function(ingif, outgif, show=TRUE, extra.opts=""){ command <- sprintf("gifsicle -O3 %s < %s > %s", extra.opts, ingif, outgif) system.fun <- if (.Platform$OS.type == "windows") shell else system if(show) message("Executing: ", strwrap(command, exdent = 2, prefix = "\n")) system.fun(ifelse(.Platform$OS.type == "windows", sprintf("\"%s\"", shQuote(command)), command)) }