1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
}
}
|