This week Dr. Alexander Salter, the son of our dear friends Diane and Bill, had an article published in the Wall Street Journal. As you can imagine, we’re all pretty chuffed about it around here. We were doing virtual high fives about it and I was trying to think of something to do to commemorate the occasion.
I got the idea to try to create one of those drawings that they use in the Wall Street Journal for the big wigs like Steve Jobs, Walter Mossberg, and Grumpy Cat. These portraits are called Hedcuts, a method which is a combination of tiny dots and little lines between them.
For the real portraits, artists painstakingly draw these tiny dots and lines, but the Wall Street Journal has developed an AI algorithm that will create a pretty good simulation. If you’re a subscriber to the Wall Street Journal, you can upload your own image and have one made. But I’m not a subscriber, and neither is Alex.
I figured there had to be a way to create a close approximation, so I went hunting on the Internets. Remember I said upfront that hedcuts are dots and lines? Well, we’re going to settle for just the dots. A drawing made with just the dots is called a stipple drawing. In case you’re interested, to stipple means to engrave by means of dots and flicks.
I found lots of tutorials on how to draw your own stipple drawings, but we know that’s not going to happen with Allison. I needed the nerd solution, and boy howdy did I find it. I discovered an open source project called StippleGen 2 by a team that goes by Evil Mad Scientist. They have a blog post about StippleGen 2 at evilmadscientist.com/…
StippleGen 2 was created in something called the Processing Development Environment, which I’d never heard of before. According to processing.org, “Processing is a flexible software sketchbook and a language for learning how to code within the context of the visual arts.”
This sure sounded fun, so I went to the Evil Mad Scientist GitHub repository github.com/… and started to poke around. I have to say, GitHub repos are not the friendliest environment if you’re not a developer. Luckily, I AM a developer, so I can teach you a little trick. If you just want to download and run the compiled software, it’s not entirely obvious how to do it.
Repos in Github do have a big green button inviting you to download the code. But you’ll get exactly that, the code behind the tool, not an app you can run. Not all repos have packaged apps, but some do.
If there is an app (or something else nicely packaged) to be downloaded, it will be on the right side under the word “Releases”. I learned this from Helma when we were working on the Taming the Terminal book. If you want to just download the latest version of this fine manual, just look for the Releases section in our repo.
Under releases on the StippleGen 2 repo you’ll find zip files for Windows (both 32 and 64-bit), Linux, Mac and even a signed version for macOS.
Ok, we’re past the first nerdy hump – double click that zip file and you’ve got yourself an app to play with. We circle right back into nerdville as soon as you launch it, because StippleGen 2 has that lovely Soviet-era UI that lets you know you’re working in an open source tool.
The majority of the app is a giant square with a drawing being created before your very eyes. It starts creating a stipple drawing upon launch using an input file of Grace Kelly. Dots, or I should say stipples, are being calculated added in successive passes which they call generations. You can press a not-very-identifiable button to load your own image as a png, jpg, or gif. Nothing against Grace, but I’ll be using a headshot of me to do the illustrations for this exercise.
Across the bottom of the image is a narrow panel that contains all of the controls. The font is simply dreadful, with no anti-aliasing and the text is wee tiny such that it’s nearly unreadable. But luckily the control sliders are super janky and hard to use, so that makes up for the font issues.
The left side of the control panel has the primary controls. It warns you that changing the primary controls will restart the process of creating your stipple drawing. Depending on your settings, creation of a good stipple drawing will take a very long time so you want to think about it before you change a primary control.
Under the primary control warning, you’ll see a slider to adjust the number of stipples. There’s a lot of math going on figuring out where the stipples go, so the more stipples you ask for, the time to calculate goes up dramatically. By default, StippleGen 2 starts with 2000 stipples, but it can go up to a maximum of 10,000 stipples. 2000 doesn’t look great but 10,000 can take a really long time.
On the right-bottom side of the control panel, you’ll see time/frame which is the same as time/generation. If you start with 2000 stipples, it takes around 7.5 seconds to generate a frame. If you drag the slider to tell it to calculate 10,000 stipples, that time per frame jumps up to nearly 800 seconds, which is over 13 minutes per generation!
While it’s working away at this task of drawing the stipples for you, you’ll see the status on the right say “Calculating Voronoi diagram”. Well clearly before we keep going learning the controls for StippleGen 2, we need to go down a rabbit hole and find out what Voronoi diagrams are. (This is why it takes me so long to write blog posts.)
According to en.wikipedia.org/…
In mathematics, a Voronoi diagram is a partition of a plane into regions close to each of a given set of objects. In the simplest case, these objects are just finitely many points in the plane (called seeds, sites, or generators). For each seed there is a corresponding region consisting of all points of the plane closer to that seed than to any other. These regions are called Voronoi cells.
So basically if you have a bunch of dots on a piece of paper, you can draw polygonal shapes around each one that connects exactly to each other. When StippleGen 2 begins calculating, you don’t see the dots, you see the Voronoi diagram being created first. I know David Roth will be disappointed that I’m not going to get into the math of how these are calculated but we simply can’t go down that route. We must be content with understanding that there is a lot of math going on and move on to making our stipple drawing look as good as possible.
I wanted to see how good the stipple drawing would look with the slider up at 10,000 stipples, but I didn’t want it running on my primary Mac all day so I set it up to run on my 2016 MacBook Pro running macOS Big Sur.
To my delight, macOS Big Sur kept spontaneously rebooting on that Mac after StippleGen 2 had been running for hours. I would restart the generation and Big Sur would do reboot again after hours of generations. It’s been suggested that perhaps the Mac was overheating (which is still no excuse), but I don’t think that’s it. Even with 10,000 stipples to calculate, StippleGen 2 uses one processor fully but doesn’t stress the other 3 in the 2016 MacBook Pro so the total load is only about 24%. It doesn’t appear to be using the GPU at all, and the CPU temperature sensor only went from 60°F at idle to around 75-80F while doing these complex calculations.
I posted in our Slack (podfeet.com/slack) about the spontaneous reboots of macOS Big Sur, and while a few others chimed in with the same thing happening to them, a couple of other people said that they have the same problem with macOS Catalina. No clue what’s going on there, but I switched over to my 2019 MacBook Pro running macOS Catalina and I was able to let StippleGen 2 run for more than a day without interruption.
While the 10K stipple run definitely looked way better than the 2K stipple render, it did take an awfully long time. The blog post from Evil Mad Genius suggested something around the 6000 stipple number would get you a pretty good image and at 11 seconds per frame, so that’s a pretty practical compromise. They also say that a pretty good image comes out after around 40 generations.
We already discussed that changing the number of stipples would start the rendering process all over again, but on the right side of the control panel, you’ll see Display Options, and modifying these options does not start the rendering process over again. The two main controls you’ll care about are the minimum dot size and the dot size range. You would think that if you set the minimum dot size really small, and the dot size range really big, you’d get the best simulated shading of an image. Oddly that’s not the case.
The minimum dot size has a range of 0.5 to 8 mysterious units, and the dot size range is from 0 to 20 mysterious units. Setting the minimum dot size to 0.5 and the dot size range to 20 actually creates an image with an excessive amount of contrast. For example, in the stipple drawing generated from my headshot, my hair becomes solid black and my shirt looks almost pure white on one side. It’s good that you can fiddle with these controls without rerendering because it does take a bit of finesse of dot size and dot size range to get an image you’ll like.
But remember upfront I told you the controls were janky and hard to use? I spent quite a while trying to find the pattern to why sometimes I could drag one of the controls and it would immediately respond to me, and other times it wouldn’t react at all. I thought maybe the buttons weren’t good representations of the true targets, so I started clicking at the top, bottom, right, and left of the buttons. Sometimes it would work and sometimes not.
Then I thought maybe it was when I tapped away to another app and came back and that’s why it reacted to my dragging the controls, but that was a red herring as well. After working with StippleGen 2 for about a week, I can finally explain why it seems persnickety on when it works and when it does not.
When StippleGen 2 first starts to render, the app is busy. Even at 2000 stipples, the beginning calculations are lengthy, and the app will pretty much only react to you right when it’s finished a generation. If you don’t catch it then, you’re waiting till the next generation. The good news is that the more generations it gets done, the faster each generation gets.
After an hour on a low number of stipples, you can drag the sliders with abandon and get pretty close to instant gratification. I let it run for more than a day with 10,000 stipples and I can play with those sliders as often as I like because it got down to 0.07 seconds per frame.
When you’ve got your sliders adjusted and your masterpiece looks pretty good, you can save your stipple file. It will save it as an SVG file, which stands for scalable vector graphics. I know, it’s just a bunch of dots but each stipple is evidently worthy of being considered a vector, even though it has neither magnitude nor direction.
If you want to save the image as a normal image file, such as a PNG or JPG, you’ll need to open up the SVG file in a vector design program. My preference is Affinity Designer, but if you don’t want to shell out any money for this little project, you can use the free Vectornator available in the Mac App Store. I’ll warn you though, that 10,000 stipple image took Vectornator to its knees while Affinity Designer had no trouble opening it.
I had to giggle at the file when I opened it in Affinity Designer. In the right sidebar, you can see the different layers and groups of layers in your document. There was one group, and inside was a separate layer for each oval. That’s right, 10,000 separate layers, each with a single oval on it. That scroll bar was TINY.
When you open up the SVG file in your vector design program, even though it’s a square image, oddly it will be on a very wide rectangle. You’ll have to select the layer for the group of ovals and then on export make sure you only export the selected layer. After all of this work, we finally have what’s a pretty decent-looking stipple image.
The bottom line is that I had a blast with this odd little tool. I enjoyed discovering it, I enjoyed figuring out how to get it out of an open source repo, I liked learning how the dots were calculated, and I was particularly pleased to finally crack the code on how to get its controls to pay attention to me. And in the end I was actually able to create a cool stipple image of my headshot.
Now here’s the punchline. There’s a free app for iOS called SnapDot that does the same thing. The only problem with SnapDot is that the sliders are super easy to use, the interface is completely obvious, it makes your stipple in about 3 seconds, and the rendered image looks a bit better than StippleGen 2. It will even make the stipples in greyscale or color for crying out loud. If you want to go the easy route and use SnapDot, then FINE. I won’t try to stop you, but I may not respect you.