summaryrefslogtreecommitdiff
path: root/convolve.js
blob: 2e59c6cf11ce64c403e0b4b94ba930b1f0310423 (plain)
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
Kernel = function (w, h, a) {
	this.w = w
	this.h = h
	this.a = a
}
Kernel.prototype.normalize = function(){
	var n = 0;
	for (var i = 0; i < this.a.length; i++)
		n += this.a[i];
	for (var i = 0; i < this.a.length; i++)
		this.a[i] /= n;
	return this
}
ConvolveOp = function (kernel, edge_zero_fill, idk) {
	var k = kernel.a
	var klen = k.length
	var kw = kernel.w
	var kh = kernel.h
	var kx = -((kw / 2)|0)
	var ky = -((kh / 2)|0)
	this.filter = function(srcImageData, destImageData){
		// assume these are both identically sized canvas objects..
		var src = srcImageData.data
		var dest = destImageData.data
		var w = srcImageData.width
		var h = srcImageData.height
		var ix, iy, it, jx, jy, jt
		var r, g, b, a

		for (var i = 0, len = w*h; i < len; i++) {
			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%kw + kx
				jy = iy + ((j/kh)|0) + ky
				jt = 4 * (jx + jy*w)
				if (0 > jx || jx > w || 0 > jy || jy > h) {
					if (edge_zero_fill) {
						continue
					}
					jt = it
				}
				r += src[jt]   * k[j]
				g += src[jt+1] * k[j]
				b += src[jt+2] * k[j]
				a += src[jt+3] * k[j]
			}
			dest[it]   = r
			dest[it+1] = g
			dest[it+2] = b
			dest[it+3] = a
		}
		return destImageData
	}
	this.convolveCanvas = function(image){
		var target = document.createElement("canvas")
		var w = target.width = image.width
		var h = target.height = image.height
		var imagectx = image.getContext('2d')
		var targetctx = target.getContext('2d')

		targetctx.drawImage(image, 0, 0);

		// get source pixels
		var src = imagectx.getImageData(0,0,w,h)
		var dest = targetctx.getImageData(0,0,w,h)

		// convolve the cloned image
		dest = this.filter(src, dest);

		targetctx.putImageData(dest, 0,0)

		return target
	}
}
ConvolveOp.prototype.EDGE_NO_OP = 0
ConvolveOp.prototype.EDGE_ZERO_FILL = 1