Wrapping Text and Making Memes

Play with the meme generator here.

The project I’m moving to on Monday is written using a different tech stack than what I’ve done previously. Instead of a web service in Spark or Play, this is a world-facing web app written in Spring Boot. I’m decently comfortable with Spring for dependency injection, so jumping in isn’t too terribly weird. I chopped up their tutorials on form submission and handling uploads and built a feature-poor meme generator.

Captioning images on the server side is a task for ImageMagick, or at least it used to be. I found Im4Java, a Java wrapper last updated in 2012, and hacked together a service method to write some text on the image:

It’s not my favorite code I’ve ever written. The wrapper library is fighting an uphill battle because you’re literally just putting a string together and then executing it as a system command, and that makes it difficult to get useful feedback. You have to call those property methods on the operation object in the correct order, since they’re just concatenating the string together. It’s frustrating. But it kinda sorta worked, and the rest of the application did some file storage and form handling stuff, and it served the purpose of “play with Spring Boot.”

Unfortunately, I didn’t have the means to compute how big the text was going to end up being on the resulting image.


When I showed this to my friend Chase Maier, he pointed out that this is a much easier task using an HTML5 Canvas – splat the image onto the canvas, draw your text, and do whatever you want with it. Now, “play with canvas again” doesn’t count for the “play with Spring Boot” part, but we’ll still be able to do our persistence in Spring Boot later.

The full source is here, but let’s focus on the js method that’s doing the equivalent of my java code above:

It’s not that the equivalent js code is much more compact than the Java code was – the important thing is that it’s easier for me to measure the width of the lines for the sake of wrapping:

The results are much prettier: