Web Monkey n'at

Apocalypse Survival is Easy.

I'm quite suprized at how easy it is to survive the end-times as predicted by mediums, prophets, clergy, mathemeticians, charlatans, and true-believers. In 2012, it was the Mayan Calendar Doomsday predictions, which were largely ignored - and later denounced - especially by Mayans. In 2011, it was Harold Camping predicting first May 21st, and when that fell through October 21st, would be the end-times as seen in Revelations. In ancient Rome there was a prophecy that 12 eagles revealed to Romulus the lifespan of Rome. Many believed each eagle to represent 10 years, bringing the end in 634 BCE; others thought the eagles represented days in a year setting the end in 389 BCE. These sorts of predictions are often made, and sometimes become popular in some circles but hardly ever come true. Some people are unduly distressed when they find themselves soon to be facing the end of the universe as we know it in a massive cosmic event, so I've decided to try and quell their fears. Maybe knowing you've likely survived a dozen or more moments of universal doom will also give you solace, knowing that the next time the world faces the final judgement probably won't be the last.

Apocalypse Survival

This single-page app fetches a JSON feed from wikipedia's List of dates predicted for apocalyptic events and parses out years, comparing them with the input year and tallying the number of failed predictions since then. It stores this data locally on initial load, and loads it from the local on subsequent loads.

find out how many apocalypses you've survived, today! or view the source on github

Glitchy 3bit dither

I'd like to officially introduce my most ambitious 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 found on tumblr and posts them to another tumblog, . I quickly set out and 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 found 3bitdither, forked it, and set out to bend 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.

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 pages 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

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 Uint32Arrays store their data like [RGBA, RGBA, RGBA, RGBA....

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.