Create video animations with Inkscape, ImageMagick and FFmpeg
Want to create an animation on GNU/Linux and then convert it to a video file? Well here is one way to do it that does not involve GIMP Animation Package (GAP). While there is nothing wrong with the GIMP GAP method, you might just find it useful to know about an alternative way of doing it that might just work for you. Maybe you are running into problems with GAP or you wish greater flexibility and control over your frames.
So let's begin.
You will need the following software:
- Inkscape (This is to create frames. You can also use GIMP, but this guide will use Inkscape.)
- ImageMagick suite (For animating.)
- FFmpeg (For converting to video.)
You will also obviously need one of the GNU/Linux distros or another free UNIX like operating system (*BSD, Solaris) and not be a total stranger to command line terminals. ;)
1. Creating frames
A big part of flexibility of this method lies in that you have absolute control over your frames. You can make them be literally anything. I recommend using Inkscape for this step because it allows great flexibility for drawing.
First we need to create a background of the size which we want our final animation to be. Let's make it 220x180 px here. Just draw a square, select it and in your "W" (width) and "H" (height) areas enter "220.000" and "180.000" respectively. The ".000" are to make sure that it is exactly of that size.
You can make the background of any color or gradient you wish. Here is mine.
It is a good idea to export this square as the first frame of your animation. It is best to create a folder in a convenient place called "animation" or whatever else you wish and export all your frames there as files named by a number. So the first frame can be a frame "0" and should be exported as 0.png. To do an export click on the square and go to File > Export bitmap. In the dialog that pops up make sure a "selection" tab is pressed and use the browse button to browse to the location you wish to save your frames in (that would be the animation folder mentioned above) and the file name you wish to save it under (0.png). Once you're done with the browse dialog click the "export" button.
Treat the background square just created as a stage. Anything that is positioned within that square is what will appear in the animation. That said, now we have to introduce the object that we want to be in the animation first which can be an image, text, a drawing etc. You can create this object by drawing or typing it yourself or you can import an existing one.
For this animation let's start with a blue circle without fill color and with a fairly fat stroke paint (border), like this:
Great. Now what I would like to do in this animation is for this circle to draw itself. The way we can accomplish that is by selecting the circle and switch to the "Edit paths by node" mode (second button on the left, or accessible by pressing F2). This will allow you to "undraw" the circle, so to speak, make only a desired part of it display. See the following image to get the idea.
"Un-drawing" it is basically setting it to the beginning position, where the circle is either not visible at all or only a very small part is visible. Export this as the next frame using the exact same process as above for the background square. Even this time, as for every other frame, it is the background square that needs to be selected as you are exporting your frame. Then everything that is within it will be exported as part of it.
I think you might already be getting the idea of where this is going. For the next frame you reveal a little more of the circle, export as frame 2.png and then draw a little more again and export as frame 3.png and so on until the whole circle is full again. The less you reveal per step the more steps or frames it takes for your circle to be drawn and the smoother will then its animation be. And this is the basis of frame creation in inkscape. Frame by frame is how animation is made. :)
To make it less daunting though, you can leave the export bitmap dialog open all the while you're exporting, and then just change the number in the file name and hit export every time you make a modification to the circle (and reselect the background).
But, we have some additional tricks up our sleeve. We can make objects fade in, thanks to Inkscape's opacity features. Here's a next object we have here:
Shiny stuff! Note that the background in this image is added only to make this object better visible. What we're to do now is superimpose this shiny element over the now completed circle to get this:
Then select it, open "Fill and stroke" settings (Object > Fill and Stroke) and move the opacity slider to near zero and then export the frame as above again, continuing to count numbers in file names. So the idea is to move a slider a little further towards 100% and export as next frame.
So far we have a circle drawing itself and nicely becoming shiney. Now you can write something in there, like your name or whatever you wish. I will write "Nuxified". :) You can use the same fade in effect with your text or you can make the typing effect by writing the first letter, exporting frame, then second etc. So, for example, first frame would be "N", then "Nu", then "Nux", then "Nuxi" etc.
The result of all this frame making and exporting should be a folder full of PNG files named from 0.png to XX.png, depending on how many you managed to make. The next step is to just put them together into an actual live animation. And that's, believe it or not, actually the easier part. :)
2. Sticking the frames together into an animation.
Open a terminal and go into the directory where your frames are. For example if your frames are in a folder called "animation" inside your home folder, just type this:
$ cd animation
Assuming you have the ImageMagick package installed all you need to do now is type something like this:
$ animate -coalesce -delay 9 0.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png 11.png 12.png 13.png 14.png 15.png 16.png 16.png 16.png 16.png 16.png 17.png 18.png 19.png 20.png 21.png 22.png 23.png 24.png 25.png 26.png 27.png 28.png 29.png 30.png 31.png 32.png 32.png 32.png 32.png 32.png 32.png 32.png 32.png 32.png 32.png
The -coalesce option is what sticks together the frame images specified. The -delay option sets how long should it pause between each frame, therefore setting the actual speed of the animation. Above it is set to "9", but you can experiment with your own values. After that we are specifying the frame files we want to stick together into an animation. This is where it helps that we have all the files named by a number. You can use tab completion to string them together faster and if you are trying multiple times you can use the up arrow to retry.
If the command is too big you can even select, copy and paste it into a text file where you can more easily tamper with it and then paste it back into the terminal for exection. You can even make it into a script, in which case you'd basically just have to save it as a filename.sh, make it executable (
chmod +x filename.sh and execute it as
./filename.sh (assuming you're executing it from the same directory).
Also notice that I have repeated 16.png five times and 32.png ten times. Repeating the same image file multiple times will have the result of that particular image being displayed longer in the animation. This is how you can control when the animation should slow down or stop to display longer.
Once the command is ran, after a while it will run the final animation in a window. To save it as a GIF file just click on that window and an ImageMagick window menu will appear.
Click animate and choose "save" and in the browse window that appears select location where to save it as well as the file name and then click the "format" button to bring up the format selection dialog.
Choose GIF and click select. Make sure your file name ends in .gif and then click save. ImageMagick should render the GIF animation to the location you specified.
Here it is. :)
3. Converting to video
Finally, as a cherry on top, we can convert this to a video file. First, we use a
convert command to convert all of the specific frames of the GIF to JPEG's which ffmpeg can stick together into a video. It's best that you move your GIF file to another directory if it's currently in the same one where your PNG frames are, just for the sake of keeping things a little tidier.
Then go into that directory and run the following on your GIF, replacing "nuxified" with your own file name.
convert nuxified.gif nuxified%05d.jpg
Now we run ffmpeg to stick them together into a video. Again just replace "nuxified" with your own name. You can set any name you desire for the final video file though.
ffmpeg -r 12 -i nuxified%05d.jpg -y -an nuxified.avi
Number 12 above sets the frame rate of the final video. You can set it to anything, but I chose 12 as it seemed optimal for this video. Of course, the higher it's set the shorter will the video last.
And here is the final product! :)
Now you can use some video editing tool to add sound to it or even put it in a larger video that you might be making. For instance, the first half of this video was done using the exact method described here. It was merged together with other parts using kdenlive.
All this may be a little on the advanced side for some, but hey, learning can be fun and once you master this, it may prove to be a very valuable addition to your skillset. You can only go so far with GIMP and you need to learn the ropes with it as well. This method is down to earth and simple. In a nutshell all we're doing is making some frames, and then sticking them together using short commands that swiftly do the job.
Finally, you can get all of the material of this tutorial by downloading this package. It contains all of the frames, generated JPEGs and final GIF and video file as well as the SVG source of the initial graphics.
Thank you for reading.