Halftone Palette
I recently stumbled upon an — old — article about the generation of halftone QR codes. It is a very impressive technique where a QR code is locally distorted to recreate an input image while maintaining its data encoding properties. I found the idea really clever, and the black and white images it involves have a really nice feel. It confirmed that the halftone effect, where an image is only composed of either black or white pixels, was something I liked a lot. So I decided to dig further.
Black and White Halftoning
Basically, it was originally developped for printing images. The idea is that, given an input grey-scale image, you can reproduce it with black ink on white paper by projecting little dots everywhere, with a high density in darker regions and a low density in brighter ones. You simply divide the original image into a grid, compute the brightness of each cell, and replace it with a dot with a proportional area. If the grid is small enough, the blurring property of the human eye averages patches of black and white dots into grey areas of varying intensities.
From that, many variations are possible to make the result less tabular. Most important ones are tilting the grid, and interlacing the rows, ie. horizontally translating one row out of two by half of the cell size.
Also, the dot shape can change:
Dot shape | Rendering |
---|---|
Circle | |
Ellipse | |
Horizontal line | |
Vertical line | |
Triangle | |
Square | |
Hexagon | |
Octagon | |
Euclidean |
The euclidean dot is an interesting one. It looks like there is a switch from black dots on white paper to white dots on black paper after 50% darkness. Actually, the grid pattern is maintained, but the dots are allowed to leak outside their cells. In the words of Kodak, the excess ink injected in one cell bridges between the dots. It is particularly suited to high and low key images.
One thing that lured me into halftoning images is the generation of pixelated images. In the above examples, dots look smooth, as we would see in paper printing: they were generated in a JavaScript canvas which, by default, applies anti-aliasing, which re-introduces grey pixels in the image. For an exactly black and white image, we want to turn that off.
Colored Halftoning
Black density can be used to reproduce grey levels. Colors can also be reproduced by varying intensities of a few primary colors, either by using additive (as in a LED screen) or subtractive (as in painting) color mixing.
Again, the idea is simple. An image is decomposed into several color channels. The basic additive basis is RGB (red, green & blue), while the basic subtractive basis is CMY (cyan, magenta & yellow). For printing, the CMYK (cyan, magenta, yellow & black) basis is often used to offer richer black tones.
For each channel, an halftone layer (often called screen) is generated. All layers are then mixed together according to some rule. In additive mixing, RGB values are simply added together. In subtractive mixing, RGB values are inversed and subtracted to the first layer, usually white.
Also, each screen is tilted differently, to avoid Moiré patterns. As we only have a 90° range, a group of CMY screens is tilted at 30°, 60° and 75°. Yellow is a brighter color, hence it is less important if it is not tilted enough.
Getting Creative
I really wanted to play with all this but failed at finding a good software for it. I have not searched a lot, so I might have missed something, but a lot of existing solutions are either very basic, do not offer a lot of customization or asking you for money. Therefore, I created my own: Halftone Palette!
It allows for everything (and a little more) detailed in this article; for instance, illustration images were generated with it. You'll find the code — and the possibility to contribute too! — on GitHub. It is far from perfect, but it allows for playing around. Here are some of the images I was able to generate: