// 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 } }