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).
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.
Good point. 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.
that is wrong way to do this - write efficient code (simple operations on an array) instead of using huge canvas library to make a library you don't need to use usable
What I thought was really cool about this though, is that I can start making a "mini-photoshop". It wouldn't be very efficient at all, but I think you could find a way to mix effects together on parts of the picture selected by the user which is what a mini-photoshop is to me. Or maybe I should just look into canvas, but at least I have the choice now.
And even if I programmatically insert inline CSS, there's always the compatibility issues and filter restrictions.
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.
I'm well versed in imagemagick to such a degree that I stopped taking on projects that would have to use it. Which is a large subset of projects. Now that I'm primarily Node and Javascript focused I'll bring this up next time.
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.
Uncaught exception: DOMException: NOT_SUPPORTED_ERR
Error thrown at line 58, column 6 in formatter(pixelData, width, height) in 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:
return formatter(newPixeldata, imgData.width, imgData.height)
called from line 147, column 4 in <anonymous function: $img.onload>() in http://grafijs.org/:
imageCtx.putImageData(grafi.invert(original), 0, 0)
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.
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: