mirza.town
about archive rss

31/08/2023

My Own Dithering Algorithm

I’ve been tinkering with the p5js library for a while now and started lino cutting recently. I wanted to combine the two and make a program that converts an image to a template for the cutting process.

After some coding and research, I found out that one can add an interesting twist to the result. If you are interested in the technical details, check out this paper; Image-based Portrait Engraving.

I’ve upload the code to GitHub if you want to play with it.

The implementation of my algorithm is pretty simple. Here’s the pseudo code;

thickness = 10
color_bands = (lighest_color - darkest_color) / thickness
for i in range(0, width):
    for j in range(0, height, thickness):
        average = [j, ..., j+thickness] / thickness

        for k in range(0, thickness):
            if average > color_bands * k:
                draw_line(i, j+k, i+thickness, j+k)

In plain English; 1. Divide the image into vertical strips of thickness pixels. 2. Get the average color of the strip. 3. Divide the color range into thickness bands. 4. Draw a line of thickness based on the average color.

Notes; - If you increase the thickness you’ll get a more color options but the thickness of the lines will increase and the final result will be more “pixelated”. - You can draw the line “symmetrically” from the center of the strip to the edges. I didn’t do that because it halves the number of possible color options. - I’ve tried quantization error but it looked like there were multiple ghost images on top of each other. Might be my implementation. :^)

Sample output;

Make it a Circle!

Radial version of the algorithm is pretty simple too. It just requires a bit of fiddling with the polar coordinates and the resolution. In my opinion, it looks better than the regular version because you can really create a focal point as can be seen in the sample below.

The pseudo code is the same as above but instead of vertical strips, we divide the image into concentric circles and calculate the brightness of the region between the circles.

Sample output;


Update; 02/09/2023

Tinkered with the algorithm a bit more and …

Typewriter Mode: Activate!

I saw James Cook’s typewriter art a long time ago and always wanted to recreate the effect. While my algorithm is not as sophisticated as his art style, I think it achieves good results - if you squint your eyes a bit. :^)

Again, the code is very similar to the regular version. The only difference is that we divide the image into a grid and calculate the average color of each cell. Then place a character based on the average color. One character doesn’t darken the area enough so the areas are filled with characters in multiple passes. At each pass the error is reduced by a factor of 2 and subtracted from the cell’s brightness. So there’s a bit of quantization error going on here.

Sample output;

If you want a more “grid” like effect;

PS; I strongly recommend you to check the images in this entry in a new tab and really zoom in.

PPS; People also call this style “op art” but I’m not completely on board with that. :^)

PPPS; I’m aware that this is not a “dithering” algorithm but I couldn’t come up with a better name for the technique. If you have any suggestions, please let me know.