Typewriter effect animation

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
User avatar
hellocatfood
Posts: 44
Joined: 2010-01-01T13:29:41-07:00
Authentication code: 8675309

Typewriter effect animation

Post by hellocatfood » 2019-02-20T03:53:21-07:00

I'm looking for a way to created an animated "typewriter" effect using imagemagick, similar to what can be done with this online tool. http://wigflip.com/screedbot/

Here's one that I made

Image

Ideally I would like to be able to read text from a .txt file (including line breaks) and have each character or word be appended and appear one character or word per image file.

I'm using ImageMagick 7.0.8-14 on Ubuntu 18.10.
Last edited by hellocatfood on 2019-02-20T09:09:59-07:00, edited 1 time in total.

snibgo
Posts: 11932
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Typewriter effect animation

Post by snibgo » 2019-02-20T09:05:17-07:00

What version of IM? On what platform?

I guess you know how to make an image from text. A script can read a text file in a loop, one pass of the loop per character, creating a new image in each pass. Finally glue the images into a GIF.
snibgo's IM pages: im.snibgo.com

User avatar
GeeMack
Posts: 709
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Typewriter effect animation

Post by GeeMack » 2019-02-20T19:49:48-07:00

hellocatfood wrote:
2019-02-20T03:53:21-07:00
Ideally I would like to be able to read text from a .txt file (including line breaks) and have each character or word be appended and appear one character or word per image file.
I've done similar tasks with animated text, so from my experience here's a concept to "type" a single line of text using IM7.

Code: Select all

magick -font courier-new-bold -pointsize 24 \
   label:"XXXXXXXXXX" -set option:each %[fx:round(u.w/10)] +delete \
   label:@textfile.txt -crop %[each]x0 -coalesce \
   -set delay 10 \( -clone -1 -set delay 50 \) -loop 0 typing.gif
That starts by setting the font and point size. Obviously a monospace font is required. After that it creates a label with a known number of characters, 10 in this example. It calculates the width of a single character and stores that value in the variable "each", then deletes that label.

Next it reads the line of text from the file "textfile.txt" and crops it into pieces one character wide using the variable "each". Those cropped pieces retain their original paging information, so "-coalesce" makes them into a sequence of images, each having one more character than the last.

To finish, it sets a delay on all the images, clones the last image and gives it a longer delay, the outputs the animated GIF.

The reason I used 10 characters for the calibrating label is because IM might add a tiny bit on each side if it's just a single character. The calculation dividing 10 characters by 10 makes it more likely to get an accurate width across the whole line of characters.

It may be necessary to use your system's "for" loop to read and manipulate multiple lines, but for a single line, this idea might get you started.

User avatar
GeeMack
Posts: 709
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Typewriter effect animation

Post by GeeMack » 2019-02-22T12:31:07-07:00

Here's a complete Windows BAT script using IM7 to accomplish the entire task...

Code: Select all

@echo off
setlocal enabledelayedexpansion

set FONT=courbd.ttf
set POINTS=18
set COUNT=0

for /f "tokens=*" %%L in ( textfile.txt ) do (
   magick ^
      -font %FONT% ^
      -pointsize %POINTS% ^
      -kerning 1 ^
      label:"\ %%L " ^
      label:"XXXXXXXXXX" ^
      -colors 16 ^
      -crop "%%[fx:round(u.w/(v.w/10))]x1@" ^
      -delete -10--1 ^
      -background white ^
      -coalesce ^
      +repage ^
      -set delay "%%[fx:t==0||t==(n-1)?75:10]" ^
      ^( ^
         -clone -1,-1,-1,-1 ^
         -distort affine "0,%%[fx:(t+1)*h/n] 0,0 " ^
         -set delay 10 ^
      ^) ^
      -loop 0 ^
         _tmp_!COUNT!.miff

   set /a COUNT+=1
)

magick _tmp_*.miff ^
   ( ^
      -clone 0--1 ^
      +repage ^
      -layers merge ^
   ) ^
   +insert ^
   -loop 0 ^
      typewriter.gif

del _tmp_*.miff

exit /b
It reads each line of "textfile.txt" and turns each line into an animated GIF letter by letter. It writes each of those results to temporary MIFF files on disk. Then it assembles all the temp files into a single animated GIF that types out each character one at a time, and scrolls from line to line to line.

A couple of caveats...

• Obviously the font must be a monospace font. NOTE: Not all monospace fonts are created equal, so a poorly written font might produce undesirable results.

• The temp files are saved with sequential numbers starting with single digits and no leading zeros, so if the text file has more than ten lines, there might be a problem with wildcard globbing and reading the temp files into the final command in the correct order. I haven't checked so I'm not sure about this.

• Because of the way Windows and ImageMagick handle certain characters, any exclamation points in the text file must be escaped with a caret "^", and any double quotes in the text file must be escaped with a backslash "\". I haven't tested this extensively, but there are probably other characters that require special handling.

• It's not a very fast script, mostly because every character in the text file becomes a separate frame of the animation, but being only a few colors, very nearly black and white, the result is a pretty small file size.

• I don't have a way to run IM7 on a *nix system, so I can't translate and test it. Windows has some pretty goofy ways to handle variables in a loop, so making it *nix friendly won't be as easy as changing end-of-line characters and escaping parentheses the way we do with simpler IM commands. If you're running *nix, you'll have to work out those details on your own.

Post Reply