Welcome to the second instalment of Digital Doodles, where I create something useless for your amusement and entertainment. If you missed out on the last one, you can find it below:
Got Something To Say?
For as long as the internet has existed, random quote generators have been with us; to provide clarity in moments of confusion, and to give our elderly relatives something to send us in the group chat. At the time of writing, Google returns roughly 40 million results for the term ‘random quote generator’ - and my extensive research (scrolling until I got bored) shows that each link is either an actual random quote generator, or a post from somebody seeking to make one for themselves.
If I could capitalise on this market, I absolutely would - but for you, dear reader, I’m going to give you something for free - and show how you too can create your own shareable quote images, with just a little work.
Conjuring Images
I’ve been playing around with ImageMagick recently - for no particular reason other than that it seems like the kind of thing that’s useful to know about. ImageMagick is a powerful image-processing utility that has terrible documentation and enormous capability - which is either a horrible combination or an interesting challenge, depending on your outlook.
In standard usage, ImageMagick allows you to take an image file, and do stuff to it programmatically - whether that’s simple transformations like resizing and cropping, or more complex adjustments like merging images together, applying filters, or overlaying text.
In this case, I wanted to channel my inner Merlin, and conjure a nice image out of thin air code, and so I ended up with the following ImageMagick script:
This script is not actually ‘valid’ ImageMagick script - the eagle-eyed and shell-literate amongst you may have noticed that I’ve included some shell expansion markup in this file:
GRAD_A: Representing a gradient start colour
GRAB_B: Representing a gradient end colour
QUOTE: Representing the quote text we want to use
In what appears to be a glaring oversight - or my own inability to read - it appears that ImageMagick itself does not understand environment variables in script files. If I’m wrong on that, I’d appreciate somebody correcting me!
Nevertheless, this is not a huge problem, so read on to find out how to make this work.
As an aside, you wouldn’t believe how long I spent trying to get ImageMagick to produce a rounded rectangle, filled with a gradient, against a drop-shadow. The final script is actually pretty straightforward, but it took a lot of trial and error to get there!
Most of the articles / tutorials I found online suggested horrible things like saving alpha masks to temporary image files, or simply starting with a pre-made image to build upon, but that seemed to go against the ethos of Digital Doodles, and I do not like defeat. Hopefully somebody tackling the same problem stumbles upon this post and realises that there is a better way!
A Quote Generator In Less Than 20 Lines
Since I’m not in the habit of maintaining my own database of interesting and inspirational quotations, I needed to source my data from somewhere.
Thankfully, there is no shortage of freely available APIs to query and retrieve quotes of any nature. In this case, I opted for the Quotable.IO API - since it’s trivial to use and returns data in an easy to parse format (JSON). Each call to the API made via the script below will return a single, randomised quote.
I also wanted to add a little variety and colour to the generated images, and so I used the excellent Colormind API - which returns a nice, coherent colour palette on each request.
With a little work to transform the returned data into something clean I could use via the jq utility, I was ready to go:
The trick to work around ImageMagick’s inability to understand environment variables can be seen in line 14 above: I read the file via the ‘cat’ command, and pass it to ‘envsubst’, which looks for the variable expansion tokens in the file and replaces them with the correct values.
Line 17 creates a ‘fake’ file from the MGK_CMD variable, which allows magick-script to read it as it would any other valid script file.
Running this script does everything required to produce what I’m sure you’ll agree are the most motivational, inspirational quote images ever to grace the internet:
Ok - admittedly, they’re not the prettiest things in the world, but considering I didn’t have to open an image editor once, it’s still pretty cool. I’m sure with a little extra work, I could improve the image quality and text clarity, and my algorithm for choosing the gradient colours (selecting the first and last colour that Colormind returns) could do with some extra thought. Occasionally, the quote itself will be too long, resulting in tiny, illegible text, but for the most part, it’s pretty passable, I’d say! Frankly, I’m impressed I got transparent backgrounds to work, so I’m calling it a win.
Make It Your Own!
If you’d like to play around with this generator, you can find both the shell script and the ImageMagick script in a GitHub gist. I’ve only written the shell script for ZSH (which you’ve got already, if you’re on a Mac), but it should be easily portable to other shells without too much fuss. For a more cross-platform solution you could try re-writing this in Python - or even make it available with a simple web-frontend and join your 40 million competitors on Google.
You could also use a different quote API entirely, if Quotable isn’t your thing. Why not try modifying the script to use the Evil Insult Generator instead?
As always, I’m interested in seeing any pointless little experiments you’ve produced and are happy to share - so if you’ve got something to show, or want to share a modification to the script I’ve shared, then feel free to drop it in the comments!
ImageMagic is a very powerful library but marred with poor documentation and security issues. Sadly, I have not come across any alternative which has as many features as ImageMagic. Python has pillow but I have not quite fully explored it, in machine learning projects people use it for quick cropping or transformations.