diff options
| author | Jules Laplace <jules@okfoc.us> | 2015-04-22 05:21:11 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2015-04-22 05:21:11 -0400 |
| commit | bef106de9fa827d983fa319cecdf688c2822efb9 (patch) | |
| tree | d336ec726e97e5c19cb0dfee56d2bf4912d0db29 /smartblur.js | |
smartblur convolution experiment
Diffstat (limited to 'smartblur.js')
| -rw-r--r-- | smartblur.js | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/smartblur.js b/smartblur.js new file mode 100644 index 0000000..181b1b4 --- /dev/null +++ b/smartblur.js @@ -0,0 +1,138 @@ + +// http://asserttrue.blogspot.ca/2010/08/implementing-smart-blur-in-java.html +SmartBlurFilter = function () { + var SENSITIVITY = 10 + var REGION_SIZE = 5 + var edge_zero_fill = true + + var kx = -((REGION_SIZE/2)|0), ky = -((REGION_SIZE/2)|0), klen = REGION_SIZE*REGION_SIZE + + var kernelArray = [ + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1 + ] + + var kernel = new Kernel(9, 9, kernelArray) + kernel.normalize() + + function lerp(a,b,amt) { + return a + amt * (b - a); + } + + function rmsError(src, i, size) { + var ave = 0; + + var len = size*size, data = src.data + + var ix, iy + var r,g,b,a + var w = src.width, h = src.height + ix = i%w + iy = (i/w)|0 + it = i * 4 + r = g = b = a = 0 + for (var j = 0; j < klen; j++) { + jx = ix + j%size + kx + jy = iy + ((j/size)|0) + ky + jt = 4 * (jx + jy*w) + if (0 > jx || jx > w || 0 > jy || jy > h) { + if (edge_zero_fill) { + continue + } + jt = it + } + r += data[jt] +// g += data[jt+1] +// b += data[jt+2] +// a += data[jt+3] + } + r /= klen +// g /= klen +// b /= klen +// a /= klen + + var diff = 0 + var accumulator = 0 + + for (var j = 0; j < klen; j++) { + jx = ix + j%size + kx + jy = iy + ((j/size)|0) + ky + jt = 4 * (jx + jy*w) + if (0 > jx || jx > w || 0 > jy || jy > h) { + if (edge_zero_fill) { + continue + } + jt = it + } + diff = data[ jt ] - ave + diff *= diff + accumulator += diff + } + + var rms = accumulator / klen + rms = Math.sqrt(rms) / 255 + return rms + } + + function lerpPixel( src, dest, blur, i, amt) { + dest[i] = lerp(src[i], blur[i], amt) + dest[i+1] = lerp(src[i+1], blur[i+1], amt) + dest[i+2] = lerp(src[i+2], blur[i+2], amt) + dest[i+3] = lerp(src[i+3], blur[i+3], amt) + } + + function blurImage( src, dest, blur, sensitivity ) { + var newPixel = 0 + var amt = 0 + var size = REGION_SIZE + var w = src.width, rms + + var srcData = src.data + var destData = dest.data + var blurData = blur.data + for (var i = 0, len = srcData.length/4; i < len; i++) { + + rms = rmsError(src, i, size) + +// amt = rms < sensitivity ? rms/sensitivity : 1.0 + lerpPixel( srcData, destData, blurData, i*4, rms) + } + + return dest + } + + this.blur = function (src_canvas, dest_canvas) { + var convolver = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); + + // clone image into target + if (! dest_canvas) dest_canvas = document.createElement("canvas") + var w = dest_canvas.width = src_canvas.width + var h = dest_canvas.height = src_canvas.height + var srcctx = src_canvas.getContext('2d') + var destctx = dest_canvas.getContext('2d') + + destctx.drawImage(src_canvas, 0, 0); + + // get source pixels + var src = srcctx.getImageData(0,0,w,h) + var dest = destctx.getImageData(0,0,w,h) + + // blur the cloned image + dest = convolver.filter(src, dest); + + destctx.putImageData(dest, 0,0) + var blurred = destctx.getImageData(0,0,w,h) + var dest = srcctx.getImageData(0,0,w,h) + dest = blurImage(src, dest, blurred, SENSITIVITY) + destctx.putImageData(dest, 0,0) + + return dest_canvas + } +}
\ No newline at end of file |
