mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
Added experimental filter section.
I added the experimental folder to show some work on filters that can be applied to an entire layer. Multiple filters can be applied to a layer (in any order, multiple times). To hook into the layer I use: layer.on('draw', filterFunc); Eventually, I would like to move that to `layer.filterFunc` and automatically apply it after the draw. `filterFunc` looks like: function filterFunc(){ // Get pixel data and create a temporary pixel buffer for working var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height); var scratchData = this.getContext().createImageData(imageData); // Apply all filters here ColorStretch(imageData,scratchData,{}); // Copy the pixel data back this.getContext().putImageData(scratchData,0,0); } `ColorStretch` is an example of a filter. It takes 3 arguments: the original image data, image data to write the result to, and an options object.
This commit is contained in:
parent
eddcf8ccbe
commit
75d0b8fe04
74
experimental/colorStretch.js
Normal file
74
experimental/colorStretch.js
Normal file
@ -0,0 +1,74 @@
|
||||
ColorStretch = (function () {
|
||||
function remap(fromValue, fromMin, fromMax, toMin, toMax) {
|
||||
|
||||
// Make sure min is less than max
|
||||
var swap;
|
||||
if (fromMin > fromMax) {
|
||||
swap = fromMax;
|
||||
fromMin = fromMax;
|
||||
fromMin = swap;
|
||||
}
|
||||
if (toMin > toMax) {
|
||||
swap = toMax;
|
||||
toMin = toMax;
|
||||
toMin = swap;
|
||||
}
|
||||
|
||||
// Compute the range of the data
|
||||
var fromRange = fromMax - fromMin;
|
||||
var toRange = toMax - toMin;
|
||||
|
||||
// If either range is 0, then the value can only be mapped to 1 value
|
||||
if (fromRange === 0) {
|
||||
return toMin + toRange / 2;
|
||||
}
|
||||
if (toRange === 0) {
|
||||
return toMin;
|
||||
}
|
||||
|
||||
// (1) untranslate, (2) unscale, (3) rescale, (4) retranslate
|
||||
var toValue = (fromValue - fromMin) / fromRange;
|
||||
toValue = (toRange * toValue) + toMin;
|
||||
|
||||
return toValue;
|
||||
}
|
||||
|
||||
// 2 PASS!
|
||||
var ColorStretch = function (src, dst, opt) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
i;
|
||||
|
||||
// 1st Pass - find the min and max for each channel:
|
||||
var rMin = srcPixels[0], rMax = rMin, r,
|
||||
gMin = srcPixels[1], gMax = gMin, g,
|
||||
bMin = srcPixels[3], bMax = bMin, b,
|
||||
aMin = srcPixels[4], aMax = aMin, a;
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
r = srcPixels[i + 0];
|
||||
if (r < rMin) { rMin = r; } else
|
||||
if (r > rMax) { rMax = r; }
|
||||
g = srcPixels[i + 1];
|
||||
if (g < gMin) { gMin = g; } else
|
||||
if (g > gMax) { gMax = g; }
|
||||
b = srcPixels[i + 2];
|
||||
if (b < bMin) { bMin = b; } else
|
||||
if (b > bMax) { bMax = b; }
|
||||
a = srcPixels[i + 3];
|
||||
if (a < aMin) { aMin = a; } else
|
||||
if (a > aMax) { aMax = a; }
|
||||
}
|
||||
|
||||
// Pass 2 - remap everything to fill the full range
|
||||
for (i = 0; i < nPixels; i += 1) {
|
||||
dstPixels[i + 0] = remap(srcPixels[i + 0], rMin, rMax, 0, 255);
|
||||
dstPixels[i + 1] = remap(srcPixels[i + 1], gMin, gMax, 0, 255);
|
||||
dstPixels[i + 2] = remap(srcPixels[i + 2], bMin, bMax, 0, 255);
|
||||
dstPixels[i + 3] = remap(srcPixels[i + 3], aMin, aMax, 0, 255);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return ColorStretch;
|
||||
})();
|
41
experimental/flip.js
Normal file
41
experimental/flip.js
Normal file
@ -0,0 +1,41 @@
|
||||
FlipX = (function () {
|
||||
var FlipX = function (src, dst, opt) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
i, m, x, y;
|
||||
for (x = 0; x < xSize; x += 1) {
|
||||
for (y = 0; y < ySize; y += 1) {
|
||||
i = (y * xSize + x) * 4; // original
|
||||
m = ((y + 1) * xSize - x) * 4; // flipped
|
||||
dstPixels[m + 0] = srcPixels[i + 0];
|
||||
dstPixels[m + 1] = srcPixels[i + 1];
|
||||
dstPixels[m + 2] = srcPixels[i + 2];
|
||||
dstPixels[m + 3] = srcPixels[i + 3];
|
||||
}
|
||||
}
|
||||
};
|
||||
return FlipX;
|
||||
})();
|
||||
|
||||
FlipY = (function () {
|
||||
var FlipY = function (src, dst, opt) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
i, m, x, y;
|
||||
for (x = 0; x < xSize; x += 1) {
|
||||
for (y = 0; y < ySize; y += 1) {
|
||||
i = (y * xSize + x) * 4; // original
|
||||
m = ((ySize - y) * xSize + x) * 4; // flipped
|
||||
dstPixels[m + 0] = srcPixels[i + 0];
|
||||
dstPixels[m + 1] = srcPixels[i + 1];
|
||||
dstPixels[m + 2] = srcPixels[i + 2];
|
||||
dstPixels[m + 3] = srcPixels[i + 3];
|
||||
}
|
||||
}
|
||||
};
|
||||
return FlipY;
|
||||
})();
|
16
experimental/grayscale.js
Normal file
16
experimental/grayscale.js
Normal file
@ -0,0 +1,16 @@
|
||||
Grayscale = (function () {
|
||||
var Grayscale = function (src, dst) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
i, brightness;
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
brightness = 0.34 * srcPixels[i] + 0.5 * srcPixels[i + 1] + 0.16 * srcPixels[i + 2];
|
||||
dstPixels[i] = brightness; // r
|
||||
dstPixels[i + 1] = brightness; // g
|
||||
dstPixels[i + 2] = brightness; // b
|
||||
dstPixels[i + 3] = srcPixels[i + 3]; // alpha
|
||||
}
|
||||
};
|
||||
return Grayscale;
|
||||
})();
|
182
experimental/index.html
Normal file
182
experimental/index.html
Normal file
@ -0,0 +1,182 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='container'></div>
|
||||
|
||||
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.6.0.min.js"></script>
|
||||
<script src="colorStretch.js"></script>
|
||||
<script src="grayscale.js"></script>
|
||||
<script src="threshold.js"></script>
|
||||
<script src="levels.js"></script>
|
||||
<script src="noise.js"></script>
|
||||
<script src="pixelate.js"></script>
|
||||
<script src="flip.js"></script>
|
||||
<script src="mirror.js"></script>
|
||||
<script src="invert.js"></script>
|
||||
<script defer="defer">
|
||||
|
||||
Hmmm = function(src,dst,opt) {
|
||||
var xSize = src.width,
|
||||
ySize = src.height,
|
||||
srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
x,y,i;
|
||||
for( x=0; x<xSize; x+=1 ){
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
i = (xSize*y + x)*4;
|
||||
dstPixels[i+0] = Math.abs(srcPixels[i+0]*Math.cos( (x*y) / opt.phase )); // 60 ~ 180/Math.PI
|
||||
dstPixels[i+1] = Math.abs(srcPixels[i+1]*Math.cos( (x*y) / opt.phase )); // 60 ~ 180/Math.PI
|
||||
dstPixels[i+2] = Math.abs(srcPixels[i+2]*Math.cos( (x*y) / opt.phase )); // 60 ~ 180/Math.PI
|
||||
dstPixels[i+3] = srcPixels[i+3];//*Math.cos( x+y / 180 ); // 60 ~ 180/Math.PI
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var createExample = (function () {
|
||||
var sn = 0;
|
||||
var createExample = function (title, filterFunc) {
|
||||
sn += 1;
|
||||
|
||||
var html = '<div>';
|
||||
html += '<h2>' + title + '</h2>';
|
||||
html += '<div id="id' + sn + '"></div>';
|
||||
html += '</div>';
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = html;
|
||||
document.getElementById('container').appendChild(div);
|
||||
|
||||
var stage = new Kinetic.Stage({
|
||||
container: 'id' + sn,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var shapesLayer = new Kinetic.Layer();
|
||||
|
||||
// The important line!
|
||||
shapesLayer.on('draw', filterFunc);
|
||||
|
||||
var triangle = new Kinetic.RegularPolygon({
|
||||
x: 190,
|
||||
y: 120,
|
||||
sides: 3,
|
||||
radius: 80,
|
||||
fillRadialGradientStartPoint: 0,
|
||||
fillRadialGradientStartRadius: 0,
|
||||
fillRadialGradientEndPoint: 0,
|
||||
fillRadialGradientEndRadius: 70,
|
||||
fillRadialGradientColorStops: [0, '#881111', 0.5, '#888811', 1, '#000088'],
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
shapesLayer.add(triangle);
|
||||
|
||||
var circle = new Kinetic.Circle({
|
||||
x: 380,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 70,
|
||||
fill: '#880000',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
shapesLayer.add(circle);
|
||||
|
||||
stage.add(shapesLayer);
|
||||
};
|
||||
return createExample;
|
||||
})();
|
||||
|
||||
createExample('Original',function(){});
|
||||
createExample('ColorStretch',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
ColorStretch(imageData,scratchData,{});
|
||||
this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
createExample('ColorStretch + Pixelate',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
ColorStretch(imageData,scratchData,{});
|
||||
Pixelate(scratchData,imageData,{width:8,height:16});
|
||||
this.getContext().putImageData(imageData,0,0);
|
||||
});
|
||||
createExample('Noise',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
Noise(imageData,scratchData,{amount:96});
|
||||
this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
createExample('Grayscale',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
Grayscale(imageData,scratchData,{});
|
||||
this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
createExample('Threshold',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
Threshold(imageData,scratchData,{level:64});
|
||||
this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
createExample('Levels',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
Levels(imageData,scratchData,{levels:4});
|
||||
this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
createExample('FlipX + FlipY',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
FlipX(imageData,scratchData,{});
|
||||
FlipY(scratchData,imageData,{});
|
||||
this.getContext().putImageData(imageData,0,0);
|
||||
|
||||
// repeat for hit canvas
|
||||
var hit = this.getHitCanvas();
|
||||
//console.info(hit);
|
||||
imageData = hit.getContext().getImageData(0,0,hit.getWidth(),hit.getHeight());
|
||||
//imageData = hit.context.getImageData(0,0,hit.getWidth(),hit.getHeight());
|
||||
FlipX(imageData,scratchData,{});
|
||||
FlipY(scratchData,imageData,{});
|
||||
hit.getContext().putImageData(imageData,0,0);
|
||||
|
||||
imageData = null;
|
||||
scratchData = null;
|
||||
});
|
||||
createExample('MirrorX + MirrorY',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
MirrorX(imageData,scratchData,{});
|
||||
MirrorY(scratchData,imageData,{});
|
||||
this.getContext().putImageData(imageData,0,0);
|
||||
//this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
|
||||
createExample('MirrorX + MirrorY + Pixelate + Color Stretch + Invert',function(){
|
||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width,this.getCanvas().height);
|
||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||
MirrorX(imageData,scratchData,{});
|
||||
MirrorY(scratchData,imageData,{});
|
||||
Pixelate(imageData,scratchData,{width:8,height:8});
|
||||
ColorStretch(scratchData,imageData,{});
|
||||
Invert(imageData,scratchData,{});
|
||||
//Noise(imageData,scratchData,{amount: 32});
|
||||
//this.getContext().putImageData(imageData,0,0);
|
||||
this.getContext().putImageData(scratchData,0,0);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
15
experimental/invert.js
Normal file
15
experimental/invert.js
Normal file
@ -0,0 +1,15 @@
|
||||
Invert = (function () {
|
||||
var Invert = function (src, dst, opt) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
i;
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
dstPixels[i+0] = 255 - srcPixels[i+0]; // r
|
||||
dstPixels[i+1] = 255 - srcPixels[i+1]; // g
|
||||
dstPixels[i+2] = 255 - srcPixels[i+2]; // b
|
||||
dstPixels[i+3] = srcPixels[i+3]; // copy alpha
|
||||
}
|
||||
};
|
||||
return Invert;
|
||||
})();
|
14
experimental/levels.js
Normal file
14
experimental/levels.js
Normal file
@ -0,0 +1,14 @@
|
||||
Levels = (function () {
|
||||
var Levels = function (src, dst, opt) {
|
||||
var nLevels = opt.levels || 2;
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
scale = (255 / nLevels),
|
||||
i;
|
||||
for (i = 0; i < nPixels; i += 1) {
|
||||
dstPixels[i] = Math.floor(srcPixels[i] / scale) * scale;
|
||||
}
|
||||
};
|
||||
return Levels;
|
||||
})();
|
55
experimental/mirror.js
Normal file
55
experimental/mirror.js
Normal file
@ -0,0 +1,55 @@
|
||||
MirrorX = (function () {
|
||||
var MirrorX = function (src, dst, opt) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = Math.ceil(xSize / 2),
|
||||
i, m, x, y;
|
||||
for (x = 0; x <= xMid; x += 1) {
|
||||
for (y = 0; y < ySize; y += 1) {
|
||||
// copy the original
|
||||
i = (y * xSize + x) * 4;
|
||||
dstPixels[i + 0] = srcPixels[i + 0];
|
||||
dstPixels[i + 1] = srcPixels[i + 1];
|
||||
dstPixels[i + 2] = srcPixels[i + 2];
|
||||
dstPixels[i + 3] = srcPixels[i + 3];
|
||||
// copy the mirrored
|
||||
m = (y * xSize + xSize - x) * 4;
|
||||
dstPixels[m + 0] = srcPixels[i + 0];
|
||||
dstPixels[m + 1] = srcPixels[i + 1];
|
||||
dstPixels[m + 2] = srcPixels[i + 2];
|
||||
dstPixels[m + 3] = srcPixels[i + 3];
|
||||
}
|
||||
}
|
||||
};
|
||||
return MirrorX;
|
||||
})();
|
||||
|
||||
MirrorY = (function () {
|
||||
var MirrorY = function (src, dst, opt) {
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
yMid = Math.ceil(ySize / 2),
|
||||
i, m, x, y;
|
||||
for (x = 0; x < xSize; x += 1) {
|
||||
for (y = 0; y <= yMid; y += 1) {
|
||||
// copy the original
|
||||
i = (y * xSize + x) * 4;
|
||||
dstPixels[i + 0] = srcPixels[i + 0];
|
||||
dstPixels[i + 1] = srcPixels[i + 1];
|
||||
dstPixels[i + 2] = srcPixels[i + 2];
|
||||
dstPixels[i + 3] = srcPixels[i + 3];
|
||||
// copy the mirrored
|
||||
m = ( (ySize-y) * xSize + x) * 4;
|
||||
dstPixels[m + 0] = srcPixels[i + 0];
|
||||
dstPixels[m + 1] = srcPixels[i + 1];
|
||||
dstPixels[m + 2] = srcPixels[i + 2];
|
||||
dstPixels[m + 3] = srcPixels[i + 3];
|
||||
}
|
||||
}
|
||||
};
|
||||
return MirrorY;
|
||||
})();
|
27
experimental/noise.js
Normal file
27
experimental/noise.js
Normal file
@ -0,0 +1,27 @@
|
||||
Noise = (function () {
|
||||
var Noise = function (src, dst, opt) {
|
||||
var amount = opt.amount || 32,
|
||||
affectAlpha = opt.affectAlpha || 0;
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
half = amount / 2,
|
||||
i;
|
||||
if (affectAlpha) {
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
dstPixels[i + 0] = srcPixels[i + 0] + half - 2 * half * Math.random();
|
||||
dstPixels[i + 1] = srcPixels[i + 1] + half - 2 * half * Math.random();
|
||||
dstPixels[i + 2] = srcPixels[i + 2] + half - 2 * half * Math.random();
|
||||
dstPixels[i + 3] = srcPixels[i + 3] + half - 2 * half * Math.random();
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
dstPixels[i + 0] = srcPixels[i + 0] + half - 2 * half * Math.random();
|
||||
dstPixels[i + 1] = srcPixels[i + 1] + half - 2 * half * Math.random();
|
||||
dstPixels[i + 2] = srcPixels[i + 2] + half - 2 * half * Math.random();
|
||||
dstPixels[i + 3] = srcPixels[i + 3];
|
||||
}
|
||||
}
|
||||
};
|
||||
return Noise;
|
||||
})();
|
94
experimental/pixelate.js
Normal file
94
experimental/pixelate.js
Normal file
@ -0,0 +1,94 @@
|
||||
Pixelate = (function () {
|
||||
var Pixelate = function (src, dst, opt) {
|
||||
|
||||
var xBinSize = opt.width || 8,
|
||||
yBinSize = opt.height || 8;
|
||||
|
||||
var xSize = src.width,
|
||||
ySize = src.height,
|
||||
srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
x, y, i;
|
||||
var pixelsPerBin = xBinSize * yBinSize,
|
||||
reds = [],
|
||||
greens = [],
|
||||
blues = [],
|
||||
alphas = [],
|
||||
red, green, blue, alpha,
|
||||
nBinsX = Math.floor(xSize / opt.width),
|
||||
nBinsY = Math.floor(ySize / opt.height),
|
||||
xBinStart, xBinEnd, yBinStart, yBinEnd,
|
||||
xBin, yBin;
|
||||
|
||||
for (xBin = 0; xBin < nBinsX; xBin += 1) {
|
||||
|
||||
// Add a new 'row'
|
||||
reds.push([]);
|
||||
greens.push([]);
|
||||
blues.push([]);
|
||||
alphas.push([]);
|
||||
|
||||
for (yBin = 0; yBin < nBinsY; yBin += 1) {
|
||||
|
||||
// Initialize all bins to 0
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
alpha = 0;
|
||||
|
||||
// Determine which pixels are included in this bin
|
||||
xBinStart = xBin * xBinSize;
|
||||
xBinEnd = xBinStart + xBinSize;
|
||||
yBinStart = yBin * yBinSize;
|
||||
yBinEnd = yBinStart + yBinSize;
|
||||
|
||||
// Add all of the pixels to this bin!
|
||||
for (x = xBinStart; x < xBinEnd; x += 1) {
|
||||
for (y = yBinStart; y < yBinEnd; y += 1) {
|
||||
i = (xSize * y + x) * 4;
|
||||
red += srcPixels[i + 0];
|
||||
green += srcPixels[i + 1];
|
||||
blue += srcPixels[i + 2];
|
||||
alpha += srcPixels[i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the pixels are between 0-255
|
||||
reds[xBin].push(red / pixelsPerBin);
|
||||
greens[xBin].push(green / pixelsPerBin);
|
||||
blues[xBin].push(blue / pixelsPerBin);
|
||||
alphas[xBin].push(alpha / pixelsPerBin);
|
||||
}
|
||||
}
|
||||
|
||||
// For each bin
|
||||
for (xBin = 0; xBin < nBinsX; xBin += 1) {
|
||||
for (yBin = 0; yBin < nBinsY; yBin += 1) {
|
||||
xBinStart = xBin * xBinSize;
|
||||
xBinEnd = xBinStart + xBinSize;
|
||||
yBinStart = yBin * yBinSize;
|
||||
yBinEnd = yBinStart + yBinSize;
|
||||
|
||||
// Draw all of the pixels at the bin's average value
|
||||
for (x = xBinStart; x < xBinEnd; x += 1) {
|
||||
for (y = yBinStart; y < yBinEnd; y += 1) {
|
||||
i = (xSize * y + x) * 4;
|
||||
dstPixels[i + 0] = reds[xBin][yBin];
|
||||
dstPixels[i + 1] = greens[xBin][yBin];
|
||||
dstPixels[i + 2] = blues[xBin][yBin];
|
||||
dstPixels[i + 3] = alphas[xBin][yBin];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I probably don't need to set these to null, but I want to make sure
|
||||
// the garabage collector removes them
|
||||
reds = null;
|
||||
greens = null;
|
||||
blues = null;
|
||||
alphas = null;
|
||||
};
|
||||
|
||||
return Pixelate;
|
||||
})();
|
17
experimental/threshold.js
Normal file
17
experimental/threshold.js
Normal file
@ -0,0 +1,17 @@
|
||||
Threshold = (function () {
|
||||
var Threshold = function (src, dst, opt) {
|
||||
var level = opt.level || 128;
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
nPixels = srcPixels.length,
|
||||
i;
|
||||
for (i = 0; i < nPixels; i += 1) {
|
||||
if (srcPixels[i] < level) {
|
||||
dstPixels[i] = 0;
|
||||
} else {
|
||||
dstPixels[i] = 255;
|
||||
}
|
||||
}
|
||||
};
|
||||
return Threshold;
|
||||
})();
|
Loading…
Reference in New Issue
Block a user