
Grafi.js – JavaScript Image Processing Library - sebg
http://grafijs.org/
======
onion2k
You can do many of these effects in plain CSS using the filter operator. As a
bonus, you get hardware acceleration if you combine them with translate3d(0,
0, 0).

~~~
feiss
That's cool, but that doesn't interfere with the library main goal:

"grafi.js is a library intended for learning about how image processing works"

~~~
dkopi
Also - CSS tricks don't work if you're writing command line tools or backend
code in JS.

~~~
onion2k
That is true, but grafi.js relies on a browser's canvas API to convert an
image to a Uint8ClampedArray of colour values, so it won't work on a command
line or backend either. As a way to learn about convolution filters it seems
fairly good though.

~~~
dkopi
Good point. [https://www.npmjs.com/package/get-
pixels](https://www.npmjs.com/package/get-pixels) can help parse an image to
pixels, but it returns a different format than the canvas API's
Uint8ClampedArray.

~~~
megalodon
I haven't tested but I think you can convert ndarray to Uint8ClampedArray by
doing

    
    
        new Uint8ClampedArray(ndarray.data);

------
_jomo
For node.js I really like lwip [0], there don't seem to be many image
processing libraries around but this one covers the most common manipulations
and it's written in C++ so it's quite fast.

0: [https://github.com/EyalAr/lwip](https://github.com/EyalAr/lwip)

~~~
dawnerd
Does it work with node 4+ now? I was using it on node 0.12 and it worked like
a champ.

~~~
_jomo
Using it with node 4.4, no issues to report.

------
phoboslab
A while ago I wrote a similar library, running on the GPU using WebGL[1].

It's interesting how the library just became a _wrapper_ around 3 very simple
pixel shaders (color matrix, convolution and blur), with the GPU doing all the
looping over each pixel for you. Imho the shaders explain the idea of each
filter much more clearly than iterative code could.

[1] [http://phoboslab.org/log/2013/11/fast-image-filters-with-
web...](http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl)

------
rasz_pl
on a browser with canvas support:

Uncaught exception: DOMException: NOT_SUPPORTED_ERR Error thrown at line 58,
column 6 in formatter(pixelData, width, height) in
[http://grafijs.org/grafi.js](http://grafijs.org/grafi.js): return new
window.ImageData(pixelData, width, height) called from line 471, column 4 in
invert(imgData) in [http://grafijs.org/grafi.js](http://grafijs.org/grafi.js):
return formatter(newPixeldata, imgData.width, imgData.height) called from line
147, column 4 in <anonymous function: $img.onload>() in
[http://grafijs.org/](http://grafijs.org/):
imageCtx.putImageData(grafi.invert(original), 0, 0)

------
greenpizza13
I have to imagine this will be entirely too slow to do any heavy lifting. Low
level matrix support is really important otherwise your convolution is big fat
nested loops.

------
Kiro
What's the point of using Uint8ClampedArray instead of just a normal array?

~~~
zschuessler
More than speed, it's easier working with the Uint8ClampedArray since the
values correlate to RGB values (0-255). If it was a matter of speed only, the
author would have used Uint32Array, which gets the speed benefit of typed
arrays but allows for larger values (meaning smaller overall array size, but
it's more complex to work with).

If you hop down to the annotated source, you can see Uint32Array used here:

[http://zschuessler.github.io/DeltaE/demos/de76-chroma-
key/](http://zschuessler.github.io/DeltaE/demos/de76-chroma-key/)

