Image Processing is an active research area and it is mostly written in C and C++ because of performance reasons. Browser makers are at war to make Javascript fast. I want to know if it is viable to do it in Javascript.
At the moment, there are really few people doing Image Processing in Javascript. I listed some examples there:
- Libraries: Processing JS, CamanJS, Pixastic, PaintBrushJS, Digitaria Image Editor, Sketchpad
- Algorithms: Face Detection, Nudity Detection, Evolving Image, Content Aware Image Resizing
Image processing is computational heavy, you have to do the same operation on millions of elements. In order to get acceptable performances we should look into all the possible ways to implement it and micro benchmark those. Today we start with the different types of Arrays.
Different types of Arrays
In Javascript there are 3 ways to get an array of data.
- Classic Arrays. The Javascript Arrays that you get using
[1, 2, 3]
ornew Array(size)
var classic = new Array(1048576);
- Canvas Data. You can access the raw pixel elements of a canvas in an array. It's an array of 4 * width * height * unsigned 8 bit integers (0 - 255).
var canvas = $('#canvas').getContext('2d').getImageData(0, 0, 512, 512).data;
- Typed Arrays. They are being introduced in Javascript for WebGL (spec).
var typed8 = new Uint8Array(1048576); var typed32 = new Uint32Array(1048576);
Benchmarks
The objective of this benchmark is to test both read and write abilities of the arrays for use in image processing. We used an array of 1 millions of elements (1024 * 1024) with random values ranging from 0 to 255. We benchmark a loop that increases all the values by one.
for (var i = 0; i < 1048576; ++i) { array[i] += 1; } |
Conclusion
Typed Arrays are not viable
Typed arrays are a new addition to Javascript and the specifications are not frozen yet. A wish would have been that they perform better as they are direct machine representation. However benchs shows us the opposite. There is probably a lot of boxing / unboxing being done behind the scene between the representation and the number
type.
One advantage of typed arrays is the ability to instantly work on a raw binary image (like p*m). All you have to do is to map your typed array to the file data part.
Since Typed Arrays are not implemented on all browsers and are slower than both classic arrays and canvas, they should not be used right now.
Classical Arrays
In both Chrome and Firefox classical arrays are faster than canvas (respectively 25% and 45%). They are containing numbers that are stored on either 32 or 64 bits (Mozilla Implementation). This is more than the 8 bits of the Canvas element.
Images are usually being stored in binary files readable either through the Canvas element or the Typed Arrays. The use of Classical Arrays requires to do 2 type conversions (loading and saving). This is a big overhead for small processing.
If you want to do heavy processing and are targeting either Firefox or Chrome, Classical Arrays may be a good choice. For more than 8 bits values it is the preferred method.
Canvas Arrays
Canvas Arrays are slower than classical arrays in Chrome and Firefox, however they are really fast on Opera. They have one huge advantage is the ability to be read and written directly through the canvas element. But they are limited to unsigned 8 bits.
If you want to do normal processing on traditional rgb values, Canvas Array is the best option. Especially on Opera where it is blazing fast.