Generating Text Title Images

Using a Ruby script and PhantomJS

In my last article, I grouped my Facebook photos during my internship by week: each week has its own photo album.

Since I might visit several places in a single week, I want to put a “title image” to separate between the photos of different places or different date on the same week.

In the end, it looks like this:

Generating the First Image

You can see that each title image has:

  • A title, which is the date in yellow;
  • A subtitle, which is the big white text; and
  • Some more text.

It can be generated using HTML and CSS by using PhantomJS to render the HTML file into the image.

Here is the corresponding HTML and CSS:

https://gist.github.com/4cbcaea315dff8bf5fb4

We can then run PhantomJS’s “rasterize.js” to turn it into an image.

If you have installed PhantomJS using Homebrew, the examples will probably be installed for you, and you can turn the HTML into the image with this command:

phantomjs /usr/local/share/phantomjs/examples/rasterize.js title_image.html title_image.png

Now, the Ruby Script

Now I want to create a script which

  1. Generates the HTML code.
  2. Puts that code into rasterize.js to generate an image, and name the file appropriately.

It turns out that we can open a Data URI with PhantomJS, so we don’t need to create any intermediate files; we can just encode the HTML file as data URI and send it to rasterize.js.

The Template

I created a template file with the same code, but changed the text into ERB tags, and named it “title.template.html.erb”. Here is the relevant part.

https://gist.github.com/dtinth/ee452a1451b4328634fb#file-title-template-html-erb

The Script

Now, I want to be able to call the script like this:

ruby title.rb "July 8" Subtitle "First Line" "Second Line" "Third Line" 5

and have it save the image into image05.cover.png.

So here is the Ruby script to accomplish that, in 11 lines.

https://gist.github.com/dtinth/ee452a1451b4328634fb#file-title-rb

And that’s it. Now I can generate title images for my album with ease.


Further Thoughts…

“Why not just use PhantomJS?,” you may ask. Although it is entirely possible to do it using just PhantomJS, Ruby gives me more expressive power than JavaScript.

I’d like to elaborate on why I chose to write the script in Ruby instead of just using JavaScript or CoffeeScript in the first place.

  • Ruby makes it very easy to unpack the ARGV. Note that in CoffeeScript, you can also accomplish the same thing with `[title, subtitle, text…, imageNumber] = phantom.args`.
  • In JavaScript and CoffeeScript, I know of no built-in way to pad a number with zeros, while in Ruby you can just `“%02d” % [x]`.
  • I am not familiar with PhantomJS’ API, but I know how to use its rasterize.js.

With these 3 thoughts, I decided to write the script in Ruby.