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:
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
- Generates the HTML code.
- 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.
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.
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.
And that’s it. Now I can generate title images for my album with ease.
- 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`.
- 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.