JSFiddle - React, Tailwind, and code Playground

by PiereDome

HTML

<script src="http://3.bp.blogspot.com/_ieToa1g-APw/TJ7A9jbAivI/AAAAAAAAACA/r-wrYjNkqw0/s1600/jack+nicholson+by+martin+schoeller+2002.jpg"></script>
<label>Image File:
<input type="file" id="imageLoader" name="imageLoader"/></label>
<select id='filters'>
  <option value='none'>(none)</option>
  <option value="blackWhite">Black and White</option>    
  <option value="greyscale">Greyscale</option>
  <option value="highlight-red">Highlight-red</option>
  <option value="highlight-green">Highlight-green</option>
  <option value="highlight-blue">Highlight-blue</option>
  <option value='negative'>Negative</option>
  <option value='mosaic'>Mosaic</option>
  <option value='sephia'>Sephia</option>
  <option value='convolute'>Convolute</option>
</select> 
<button id='encode'>Filter</button>
<canvas id='canvas'></canvas>
<canvas id='canvas2'></canvas>

CSS

#canvas, #canvas2{
    position: absolute;
    top: 25px;
    left: -100px;
}

JavaScript

var Filter = (function() {
    var greyscale = function(frame) {
        var l = frame.data.length;
        for (var i = 0; i < l; i += 4) {
            var average = Math.floor((frame.data[i] + frame.data[i + 1] + frame.data[i + 2]) / 3);
            frame.data[i] = average;
            frame.data[i + 1] = average;
            frame.data[i + 2] = average;
        }
        return frame;
    };

    convolute = function(frame, weights, opaque) {
        var side = Math.round(Math.sqrt(weights.length));
        var halfSide = Math.floor(side / 2);
        var src = frame.data;
        //var sw 
        var w = frame.width;
        //var sw
        var h = frame.height;
        // pad output by the convolution matrix   
        //var w = sw;
        //var h = sh;
        var output = ctx.createImageData(w, h);
        var dst = output.data; // go through the destination image pixels   
        var alphaFac = opaque ? 1 : 0;
        for (var y = 0; y < h; y++) {
            for (var x = 0; x < w; x++) {
                var sy = y;
                var sx = x;
                var dstOff = (y * w + x) * 4; // calculate the weighed sum of the source image pixels that       // fall under the convolution matrix       
                var r = 0,
                    g = 0,
                    b = 0,
                    a = 0;
                for (var cy = 0; cy < side; cy++) {
                    for (var cx = 0; cx < side; cx++) {
                        var scy = sy + cy - halfSide;
                        var scx = sx + cx - halfSide;
                        if (scy >= 0 && scy < h && scx >= 0 && scx < w) {
                            var srcOff = (scy * w + scx) * 4;
                            var wt = weights[cy * side + cx];
                            r += src[srcOff] * wt;
                            g += src[srcOff + 1] * wt;
                            b += src[srcOff + 2] * wt;
                            a += src[srcOff + 3] * wt;
                        }
    ...