UPDATE: Fixed the commands not displaying properly
Step by step guide on creating ASCII animation from GIFs in shell
Howdy, fellow terminal connoiseur. Is writing configs and shell scripts for managing your system not satisfying enough? Perhaps you seek a creative outlet, but do not wish to leave your beloved monochrome screen - if that's the case, this short guide might just offer you a little something to do and impress your GUI-obsessed friends.
The result of this guide will output something akin to the camel above. Note that results will warry depending on the choice of font and your own color scheme.
All in all we will use automatisation to create our ASCII animation utilising two opensource programs.
Before we get into the process of turning a GIF into an ASCII animation, we need to obtain the GIF itself. If you only want to try this guide without the hassle of finding a suitable animation, you can use the following GIF of a walking camel I provide.
I created this animation by rotoscoping (tracing) a cycle of a camel walk in GIMP. You are free to do with it as you please.
Download the picture the usual way you would. Right click it in a browser and save it, or use any other tools that are available to you: ie:
$ ftp http://www.triapul.cz/img/camel.gif
Use whatever methods you prefer to obtain these two programs. Here are official links to both projects, if you want to build them from source and/or read about them.
For whatever reason I failed to build jp2a on OpenBSD. If you try and are successful, do let me know.ImageMagick jp2a
Otherwise use your package manager. ie:
# pkg install jp2a ImageMagick7 #on FreeBSD
# apt install jp2a ImageMagick #on debian and its derivates
Let's start by making a working directory for our project and place the camel.gif there.
Unless you haven't already, open a terminal inside the working directory. Converting the GIF into frames in the simplest terms is a matter of:
$ convert camel.gif camel.png
In our case of camel.gif, this will only take a second. You can $ ls *png to make sure the frames are there. ls should output 8 files, starting with camel-0.png
An Ubuntu user reported that their jp2a build from packages doesn't work with pngs. If that's the case for you, convert the GIF into jpegs instead. $ convert camel.gif camel.jpg. I opted for pngs on account of transparency when working with a GIF that has no background, but for our case, when the animation is on a white background, it will not matter. If you are working with jpegs instead, replace all following instances of png with jpg.
Now we can test how jp2a will process our png frames. Let's see what happens when we run:
$ jp2a camel-0.png
'cl:od xkxxkK' ,dd. OdlddddoldkK ;dlkolddddddddddlok. ,oddddddddddddddl;. .odlo. :ddo :o .,. ., co ;. .x ,' '0. x. :.
Note that by default jp2a will scale its output based on the size of your terminal window.
We could convert each frame by hand, or we can automatise it using the 'for loop'. The following command will convert all png files inside the directory.
$ for FRAME in $(ls *png); do jp2a $FRAME > $FRAME.txt; done
Check that our working directory now contains the converted pngs in text files.
$ ls *txt
As of now, this has been my simplest method of playing our soon to be ASCII animation on loop.
Again, we will utilise the 'for loop,' nested inside an endless 'while loop'.
$ while true; do for FRAME in $(ls *txt | sort -V); do clear; cat $FRAME; sleep .1; done; done
Looks good! You can stop the animation with Ctrl-C.
These are my first impressions on making ASCII animations in shell. I aim to provide a follow-up, when I fine tune the results. My eventual target is to provide a single file shell script containing all frames, which in itself is not a daunting task, but I find it important to describe the underlying processes. Different terminal emulators provide different results with 'clear,' which might not be the perfect solution.
There are many caveats regarding different GIFS, which I aim to address in a follow-up.
If jp2a outputs the ASCII frames with a filled background, try the -i flag to make the background transparent