Hacker News new | past | comments | ask | show | jobs | submit login
Grafi.js – JavaScript Image Processing Library (grafijs.org)
113 points by sebg on April 26, 2016 | hide | past | favorite | 24 comments



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'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"


I saw Mariko give a talk about this last week - http://2016.render-conf.com/talks#drawing-on-canvas-a-few-th...

It was absolutely fantastic; really great information about image data & how to process it.


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


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.


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

    new Uint8ClampedArray(ndarray.data);


Node-canvas provides a compliant Canvas implementation:

https://github.com/Automattic/node-canvas


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


And she beats the purpose instantly by adding this to the readme:

    they code is pretty rough & documentation is not great
There are much better tutorials out there for image processing: http://www.html5rocks.com/en/tutorials/canvas/imagefilters/


The better way of triggering hardware acceleration nowadays is with the CSS will-change API: https://developer.mozilla.org/en-US/docs/Web/CSS/will-change


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.


Photo editing using webgl already existed for a couple years now:

http://evanw.github.io/webgl-filter/

http://photogl.net/

https://v3.polarr.co/ (this one seems to be the only real company instead of a demo)


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


This looks excellent.

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.


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


Using it with node 4.4, no issues to report.


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


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: 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.


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


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/



asm.js




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: