Web Yinzer

Glitchy 3bit dither

I’d like to officially introduce my new pet project, Glitchy 3bit Dither, it’s an in-browser emulation of glitch art techniques. In the past I’ve tried my hand at circuit bending, creatively short-circuiting and modifying physical devices. I’ve even played with more traditional glitches, but was inspired to create my own software to do so after seeing rumblesan. His cuttr project glitches images from on tumblr and posts them to another tumblog, . I quickly created a python script using PIL to start glitching images from instagram. I started writing the tumblr code, but I didn’t like the lack of control, and I didn’t really want to make a rumblesan clone. Besides, how can you create art without the artist’s input? After seeing caman.js*, I knew I could do it in javascript, thanks to canvas. During my research I discovered 3bitdither, forked it, and bent it to my will.


Here’s a short list of some of the functions I’ve implemented.

  1. Random dithering rates each pixel against a random value, if it’s higher than that value it’s a white pixel, if it’s lower it’s black. I’ve also colorized it by rating each channel value of the pixel.
  2. Color shifting will play with the values by boosting or re-arranging the red, green, or blue channels.
  3. Slices move chunks of pixel and channel values in interesting ways, sometimes shifting colors as well.
  4. Sorts Sort chunks of pixels in place, producing gradient-like stripes of colors within the image.
  5. Fractals Create fractal-like ghosts and shadows by repeating an image on itself

This is a work in progress, so all of the code is subject to change; also I’m working on updating this to work with node.js on a separate branch*, so all the code will have to be adjusted for that anyhow.


There are 4 different interfaces here, each offering their own unique take on the task,

  1. Demo will run each function against the original image once
  2. Glitch Only will apply a random set of glitches to the original image several times
  3. Glitch Cruiser When you upload an image it appears in the center surrounded by 8 glitchy alternatives. If one of these images suits your fancy, click on it and it will become the new source for the next round of glitches. If you do not like any of the suggested glitches, click on the center image, and you’ll get the next 8 glitch options, but your source will not be changed. Lena, and 8 possibilities
  4. Glitch Chooser this allows you to select functions from a drop-down list to apply to an image, you can either apply a tranformation, or reset it to the way it was before, you can even reset it to the original image. Unliked Glitch Cruiser, you won’t be able to see the results of a function before selecting it, but you can replace the latest image transformation again and again until you can see your desired results.

Technical Notes

imageData.data is a Uint8ClampedArray, one of the new Typed Arrays in javascript. They’re part of the WebGL spec and should be available in all modern browsers. This array holds all the data for every pixel in the image, however it’s stores 8-bit values, channel-by-channel instead of pixel-by-pixel, that is to say Uint8ClampedArray stores the image data like [R,G,B,A,R,G,B,A,R,G...]. This means that to deal with this array, you’re going to have to increment the loop by 4, and handle the channel-values each time like this function that inverts a pixel’s color:

    var Uint8Arr = imageData.data;
    for(var i = 0; i < Uint8Arr.length; i += 4){
        /* simple invert */
        Uint8Arr[i] -= 255;
        Uint8Arr[i+1] -= 255;
        Uint8Arr[i+2] -= 255;

This is a slow & tedious task, but there are other typed arrays, like Uint32Array which stores 32-bit values, converting an 8-bit array to a 32-bit array would cut the size of the array by a quarter. So as a Uint32Array color data is stored like [ARGB, ARGB, ARGB, ARGB..., inverting is now just one operation.

    var Uint32Arr = new Uint32Array(imageData.data.buffer);
    for(var i = 0; i < Uint32Arr.length; i++){
        /* bitwise invert */
        Uint32Arr[i] = ~Uint32Arr[i] | 0xFF000000;

Here, a bitwise NOT (~) inverts the bits, and OR | applies a mask to keep the alpha channel at 100%. You may also notice that I’m using the imageData.data.buffer to make a 32-bit view of the 8-bit data, this means that you don’t have to set the data back into the array, because it passes through to the original variable naturally.

While all the above is true for most personal computers which store data in Little Endian, some other machines may use Big Endian notations, which would reverse the order of the data from RGBA to ABGR. If you were making imaging software you’d probably want to account for that, but since the point of this project is to maim images it’s only mildly important to ensure the alpha channel is applied correctly (or just set to 100%.)

* now that I’m planning to make this into a node-based tool, and eventually distribute it on NPM, I’m thinking I’d be better off making this an extension of camanjs because they’ve already got so much figured out. Also I think by that point a name change might be in order.