summaryrefslogtreecommitdiff
path: root/canvasquery.dither.js
diff options
context:
space:
mode:
authorJulie Lala <jules@okfoc.us>2013-12-10 00:47:36 -0500
committerJulie Lala <jules@okfoc.us>2013-12-10 00:47:36 -0500
commit037a0ae8072217f7821549bbdfe030e73289330d (patch)
treeb2e20cff097a44e08cd8e6609e7d5a00b732d88c /canvasquery.dither.js
dither stuff
Diffstat (limited to 'canvasquery.dither.js')
-rw-r--r--canvasquery.dither.js217
1 files changed, 217 insertions, 0 deletions
diff --git a/canvasquery.dither.js b/canvasquery.dither.js
new file mode 100644
index 0000000..a76ad12
--- /dev/null
+++ b/canvasquery.dither.js
@@ -0,0 +1,217 @@
+var patterns = {}
+patterns[2] = [ 0, 2,
+ 3, 1 ]
+
+patterns[3] = [ 0, 5, 3,
+ 8, 1, 6,
+ 4, 7, 2, ]
+
+patterns[4] = [ 0, 8, 2, 10,
+ 6, 14, 4, 12,
+ 3, 11, 1, 9,
+ 5, 13, 7, 15 ]
+
+CanvasQuery.Wrapper.prototype.threshold = function(factor) {
+ var bitmap = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
+ var bitmapData = bitmap.data
+
+ var width = this.canvas.width
+ var height = this.canvas.height
+
+ if (factor < 1) factor *= 255
+
+ for (var i = 0; i < height; i++) {
+ for (var j = 0; j < width; j++) {
+ var a = 4 * (i*width + j)
+ var val = (bitmapData[a] + bitmapData[a+1] + bitmapData[a+2]) / 3
+ var lum = val > factor ? 255 : 0
+ bitmapData[a] = bitmapData[a+1] = bitmapData[a+2] = lum
+ }
+ }
+ this.context.putImageData(bitmap, 0, 0);
+ return this;
+}
+
+CanvasQuery.Wrapper.prototype.randomDither = function() {
+ var bitmap = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
+ var bitmapData = bitmap.data
+
+ var width = this.canvas.width
+ var height = this.canvas.height
+
+ for (var i = 0; i < height; i++) {
+ for (var j = 0; j < width; j++) {
+ var a = 4 * (i*width + j)
+ var val = (bitmapData[a] + bitmapData[a+1] + bitmapData[a+2]) / (3*255)
+ var lum = val > Math.random() ? 255 : 0
+ bitmapData[a] = bitmapData[a+1] = bitmapData[a+2] = lum
+ }
+ }
+ this.context.putImageData(bitmap, 0, 0);
+ return this;
+}
+
+CanvasQuery.Wrapper.prototype.pattern2Dither = function() {
+ this.patternDither(2)
+}
+CanvasQuery.Wrapper.prototype.pattern3Dither = function() {
+ this.patternDither(3)
+}
+CanvasQuery.Wrapper.prototype.pattern4Dither = function() {
+ this.patternDither(4)
+}
+CanvasQuery.Wrapper.prototype.patternDither = function(n) {
+ var bitmap = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
+ var bitmapData = bitmap.data
+
+ var width = this.canvas.width
+ var height = this.canvas.height
+
+ var pat = patterns[n]
+ var len = pat.length - 1
+
+ for (var i = 0; i < height; i++) {
+ for (var j = 0; j < width; j++) {
+ var p = ((i % n) * n) + (j % n)
+ var a = 4 * (i*width + j)
+ var val = (bitmapData[a] + bitmapData[a+1] + bitmapData[a+2]) / (3*255)
+ var lum = val > pat[p]/len ? 255 : 0
+ bitmapData[a] = bitmapData[a+1] = bitmapData[a+2] = lum
+ }
+ }
+ this.context.putImageData(bitmap, 0, 0);
+ return this;
+}
+
+CanvasQuery.Wrapper.prototype.pattern2LiteDither = function() {
+ this.patternLiteDither(2)
+}
+CanvasQuery.Wrapper.prototype.pattern3LiteDither = function() {
+ this.patternLiteDither(3)
+}
+CanvasQuery.Wrapper.prototype.pattern4LiteDither = function() {
+ this.patternLiteDither(4)
+}
+CanvasQuery.Wrapper.prototype.patternLiteDither = function(n) {
+ var bitmap = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
+ var bitmapData = bitmap.data
+
+ var width = this.canvas.width
+ var height = this.canvas.height
+
+ var pat = patterns[n]
+ var len = pat.length
+
+ for (var i = 0; i < height; i++) {
+ for (var j = 0; j < width; j++) {
+ var p = ((i % n) * n) + (j % n)
+ var a = 4 * (i*width + j)
+ var val = (bitmapData[a] + bitmapData[a+1] + bitmapData[a+2]) / (3*255)
+ var lum = val > pat[p]/len ? 255 : 0
+ bitmapData[a] = bitmapData[a+1] = bitmapData[a+2] = lum
+ }
+ }
+ this.context.putImageData(bitmap, 0, 0);
+ return this;
+}
+
+CanvasQuery.Wrapper.prototype.floydSteinbergDither = function(n) {
+ var bitmap = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
+ var bitmapData = bitmap.data
+
+ var mask = this.grayscaleToMask()
+
+ var width = this.canvas.width
+ var height = this.canvas.height
+
+ for (var y = 0; y < height; y++) {
+ for (var x = 0; x < width; x++) {
+ var p = (y*width + x)
+ var a = 4 * p
+ var val = mask[p]
+ var lum = val > 127 ? 255 : 0
+ var error = val - lum
+ if (x < width-1)
+ mask[ (y*width) + x+1 ] += 7/16 * error
+ if (y < height-1 && x > 0)
+ mask[ ((y+1)*width) + x-1 ] += 5/16 * error
+ if (y < height-1)
+ mask[ ((y+1)*width) + x ] += 3/16 * error
+ if (y < height-1 && x < width-1)
+ mask[ ((y+1)*width) + x+1 ] += 1/16 * error
+ bitmapData[a] = bitmapData[a+1] = bitmapData[a+2] = lum
+ }
+ }
+ this.context.putImageData(bitmap, 0, 0);
+ return this;
+}
+
+CanvasQuery.Wrapper.prototype.rightDither = function(n) {
+ var bitmap = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
+ var bitmapData = bitmap.data
+
+ var mask = this.grayscaleToMask()
+
+ var width = this.canvas.width
+ var height = this.canvas.height
+
+ for (var y = 0; y < height; y++) {
+ for (var x = 0; x < width; x++) {
+ var p = (y*width + x)
+ var a = 4 * p
+ var val = mask[p]
+ var lum = val > 127 ? 255 : 0
+ var error = val - lum
+ if (x < width-1)
+ mask[ (y*width) + x+1 ] += 7/16 * error
+ bitmapData[a] = bitmapData[a+1] = bitmapData[a+2] = lum
+ }
+ }
+ this.context.putImageData(bitmap, 0, 0);
+ return this;
+}
+
+CanvasQuery.Wrapper.prototype.halftone = function(radius, angle) {
+ var mask = this.grayscaleToMask()
+
+ this.fillStyle("#fff")
+ this.fillRect(0, 0, this.canvas.width, this.canvas.height)
+
+ var diameter = radius*2
+ var TWO_PI = Math.PI*2
+
+ var angle = angle / 180 * Math.PI
+
+ var cos = Math.cos(angle)
+ var sin = Math.sin(angle)
+
+ var xstep = cos * radius
+ var ystep = sin * radius
+
+ var w = this.canvas.width
+ var h = this.canvas.height
+
+ this.fillStyle("#000")
+
+ for (var i = -w; i < w; i++) {
+ for (var j = -h; j < h; j++) {
+ var x = i * ystep - j * xstep
+ var y = i * xstep + j * ystep
+ if (x > -diameter && y > -diameter && x < w+diameter && y < h+diameter) {
+ circle(this,x,y)
+ }
+ }
+ }
+
+ function circle(cq,x,y) {
+ var xx = x < 0 ? 0 : x > w ? w - 1 : x;
+ var yy = y < 0 ? 0 : y > h ? h - 1 : y;
+ var r = (1 - Math.pow( mask[ ~~(~~yy*w+(xx)) ] / 255, Math.E/4 )) * radius
+ cq.beginPath()
+ .arc(x,y,r,0,TWO_PI)
+ .closePath()
+ .fill();
+ }
+ return this;
+}
+