mirror of
https://github.com/konvajs/konva.git
synced 2026-01-23 05:14:58 +08:00
only lint errors fixes
This commit is contained in:
@@ -68,7 +68,8 @@
|
||||
451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,
|
||||
385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,
|
||||
332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,
|
||||
289,287,285,282,280,278,275,273,271,269,267,265,263,261,259];
|
||||
289,287,285,282,280,278,275,273,271,269,267,265,263,261,259
|
||||
];
|
||||
|
||||
var shg_table = [
|
||||
9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
|
||||
@@ -86,7 +87,8 @@
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 ];
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24
|
||||
];
|
||||
|
||||
function filterGaussBlurRGBA( imageData, radius) {
|
||||
|
||||
@@ -114,7 +116,9 @@
|
||||
|
||||
for ( i = 1; i < div; i++ ) {
|
||||
stack = stack.next = new BlurStack();
|
||||
if ( i == radiusPlus1 ) stackEnd = stack;
|
||||
if ( i == radiusPlus1 ){
|
||||
stackEnd = stack;
|
||||
}
|
||||
}
|
||||
|
||||
stack.next = stackStart;
|
||||
|
||||
@@ -1,169 +1,175 @@
|
||||
(function () {
|
||||
/**
|
||||
* Emboss Filter
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* Pixastic Lib - Emboss filter - v0.1.0
|
||||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
||||
* License: [http://www.pixastic.com/lib/license.txt]
|
||||
*/
|
||||
Kinetic.Filters.Emboss = function (imageData) {
|
||||
/**
|
||||
* Emboss Filter
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* Pixastic Lib - Emboss filter - v0.1.0
|
||||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
||||
* License: [http://www.pixastic.com/lib/license.txt]
|
||||
*/
|
||||
Kinetic.Filters.Emboss = function (imageData) {
|
||||
|
||||
// pixastic strength is between 0 and 10. I want it between 0 and 1
|
||||
// pixastic greyLevel is between 0 and 255. I want it between 0 and 1. Also,
|
||||
// a max value of greyLevel yields a white emboss, and the min value yields a black
|
||||
// emboss. Therefore, I changed greyLevel to whiteLevel
|
||||
var strength = this.embossStrength() * 10,
|
||||
greyLevel = this.embossWhiteLevel() * 255,
|
||||
direction = this.embossDirection(),
|
||||
blend = this.embossBlend(),
|
||||
dirY = 0,
|
||||
dirX = 0,
|
||||
data = imageData.data,
|
||||
invertAlpha = false,
|
||||
w = imageData.width,
|
||||
h = imageData.height,
|
||||
w4 = w*4,
|
||||
y = h;
|
||||
// pixastic strength is between 0 and 10. I want it between 0 and 1
|
||||
// pixastic greyLevel is between 0 and 255. I want it between 0 and 1. Also,
|
||||
// a max value of greyLevel yields a white emboss, and the min value yields a black
|
||||
// emboss. Therefore, I changed greyLevel to whiteLevel
|
||||
var strength = this.embossStrength() * 10,
|
||||
greyLevel = this.embossWhiteLevel() * 255,
|
||||
direction = this.embossDirection(),
|
||||
blend = this.embossBlend(),
|
||||
dirY = 0,
|
||||
dirX = 0,
|
||||
data = imageData.data,
|
||||
w = imageData.width,
|
||||
h = imageData.height,
|
||||
w4 = w*4,
|
||||
y = h;
|
||||
|
||||
switch (direction) {
|
||||
case 'top-left':
|
||||
dirY = -1;
|
||||
dirX = -1;
|
||||
break;
|
||||
case 'top':
|
||||
dirY = -1;
|
||||
dirX = 0;
|
||||
break;
|
||||
case 'top-right':
|
||||
dirY = -1;
|
||||
dirX = 1;
|
||||
break;
|
||||
case 'right':
|
||||
dirY = 0;
|
||||
dirX = 1;
|
||||
break;
|
||||
case 'bottom-right':
|
||||
dirY = 1;
|
||||
dirX = 1;
|
||||
break;
|
||||
case 'bottom':
|
||||
dirY = 1;
|
||||
dirX = 0;
|
||||
break;
|
||||
case 'bottom-left':
|
||||
dirY = 1;
|
||||
dirX = -1;
|
||||
break;
|
||||
case 'left':
|
||||
dirY = 0;
|
||||
dirX = -1;
|
||||
break;
|
||||
}
|
||||
switch (direction) {
|
||||
case 'top-left':
|
||||
dirY = -1;
|
||||
dirX = -1;
|
||||
break;
|
||||
case 'top':
|
||||
dirY = -1;
|
||||
dirX = 0;
|
||||
break;
|
||||
case 'top-right':
|
||||
dirY = -1;
|
||||
dirX = 1;
|
||||
break;
|
||||
case 'right':
|
||||
dirY = 0;
|
||||
dirX = 1;
|
||||
break;
|
||||
case 'bottom-right':
|
||||
dirY = 1;
|
||||
dirX = 1;
|
||||
break;
|
||||
case 'bottom':
|
||||
dirY = 1;
|
||||
dirX = 0;
|
||||
break;
|
||||
case 'bottom-left':
|
||||
dirY = 1;
|
||||
dirX = -1;
|
||||
break;
|
||||
case 'left':
|
||||
dirY = 0;
|
||||
dirX = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
var offsetY = (y-1)*w4;
|
||||
|
||||
var otherY = dirY;
|
||||
if (y + otherY < 1) otherY = 0;
|
||||
if (y + otherY > h) otherY = 0;
|
||||
|
||||
var offsetYOther = (y-1+otherY)*w*4;
|
||||
|
||||
var x = w;
|
||||
do {
|
||||
var offset = offsetY + (x-1)*4;
|
||||
var offsetY = (y-1)*w4;
|
||||
|
||||
var otherX = dirX;
|
||||
if (x + otherX < 1) otherX = 0;
|
||||
if (x + otherX > w) otherX = 0;
|
||||
|
||||
var offsetOther = offsetYOther + (x-1+otherX)*4;
|
||||
|
||||
var dR = data[offset] - data[offsetOther];
|
||||
var dG = data[offset+1] - data[offsetOther+1];
|
||||
var dB = data[offset+2] - data[offsetOther+2];
|
||||
|
||||
var dif = dR;
|
||||
var absDif = dif > 0 ? dif : -dif;
|
||||
|
||||
var absG = dG > 0 ? dG : -dG;
|
||||
var absB = dB > 0 ? dB : -dB;
|
||||
|
||||
if (absG > absDif) {
|
||||
dif = dG;
|
||||
var otherY = dirY;
|
||||
if (y + otherY < 1){
|
||||
otherY = 0;
|
||||
}
|
||||
if (absB > absDif) {
|
||||
dif = dB;
|
||||
if (y + otherY > h) {
|
||||
otherY = 0;
|
||||
}
|
||||
|
||||
dif *= strength;
|
||||
var offsetYOther = (y-1+otherY)*w*4;
|
||||
|
||||
if (blend) {
|
||||
var r = data[offset] + dif;
|
||||
var g = data[offset+1] + dif;
|
||||
var b = data[offset+2] + dif;
|
||||
var x = w;
|
||||
do {
|
||||
var offset = offsetY + (x-1)*4;
|
||||
|
||||
data[offset] = (r > 255) ? 255 : (r < 0 ? 0 : r);
|
||||
data[offset+1] = (g > 255) ? 255 : (g < 0 ? 0 : g);
|
||||
data[offset+2] = (b > 255) ? 255 : (b < 0 ? 0 : b);
|
||||
} else {
|
||||
var grey = greyLevel - dif;
|
||||
if (grey < 0) {
|
||||
grey = 0;
|
||||
} else if (grey > 255) {
|
||||
grey = 255;
|
||||
}
|
||||
var otherX = dirX;
|
||||
if (x + otherX < 1){
|
||||
otherX = 0;
|
||||
}
|
||||
if (x + otherX > w) {
|
||||
otherX = 0;
|
||||
}
|
||||
|
||||
data[offset] = data[offset+1] = data[offset+2] = grey;
|
||||
}
|
||||
var offsetOther = offsetYOther + (x-1+otherX)*4;
|
||||
|
||||
} while (--x);
|
||||
} while (--y);
|
||||
};
|
||||
var dR = data[offset] - data[offsetOther];
|
||||
var dG = data[offset+1] - data[offsetOther+1];
|
||||
var dB = data[offset+2] - data[offsetOther+2];
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossStrength', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss strength
|
||||
* @name embossStrength
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} level between 0 and 1. Default is 0.5
|
||||
* @returns {Number}
|
||||
*/
|
||||
var dif = dR;
|
||||
var absDif = dif > 0 ? dif : -dif;
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossWhiteLevel', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss white level
|
||||
* @name embossWhiteLevel
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} embossWhiteLevel between 0 and 1. Default is 0.5
|
||||
* @returns {Number}
|
||||
*/
|
||||
var absG = dG > 0 ? dG : -dG;
|
||||
var absB = dB > 0 ? dB : -dB;
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossDirection', 'top-left', null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss direction
|
||||
* @name embossDirection
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {String} embossDirection can be top-left, top, top-right, right, bottom-right, bottom, bottom-left or left
|
||||
* The default is top-left
|
||||
* @returns {String}
|
||||
*/
|
||||
if (absG > absDif) {
|
||||
dif = dG;
|
||||
}
|
||||
if (absB > absDif) {
|
||||
dif = dB;
|
||||
}
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossBlend', false, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss blend
|
||||
* @name embossBlend
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Boolean} embossBlend
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
dif *= strength;
|
||||
|
||||
if (blend) {
|
||||
var r = data[offset] + dif;
|
||||
var g = data[offset+1] + dif;
|
||||
var b = data[offset+2] + dif;
|
||||
|
||||
data[offset] = (r > 255) ? 255 : (r < 0 ? 0 : r);
|
||||
data[offset+1] = (g > 255) ? 255 : (g < 0 ? 0 : g);
|
||||
data[offset+2] = (b > 255) ? 255 : (b < 0 ? 0 : b);
|
||||
} else {
|
||||
var grey = greyLevel - dif;
|
||||
if (grey < 0) {
|
||||
grey = 0;
|
||||
} else if (grey > 255) {
|
||||
grey = 255;
|
||||
}
|
||||
|
||||
data[offset] = data[offset+1] = data[offset+2] = grey;
|
||||
}
|
||||
|
||||
} while (--x);
|
||||
} while (--y);
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossStrength', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss strength
|
||||
* @name embossStrength
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} level between 0 and 1. Default is 0.5
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossWhiteLevel', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss white level
|
||||
* @name embossWhiteLevel
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} embossWhiteLevel between 0 and 1. Default is 0.5
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossDirection', 'top-left', null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss direction
|
||||
* @name embossDirection
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {String} embossDirection can be top-left, top, top-right, right, bottom-right, bottom, bottom-left or left
|
||||
* The default is top-left
|
||||
* @returns {String}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'embossBlend', false, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set emboss blend
|
||||
* @name embossBlend
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Boolean} embossBlend
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
})();
|
||||
|
||||
|
||||
|
||||
@@ -1,111 +1,111 @@
|
||||
(function () {
|
||||
function remap(fromValue, fromMin, fromMax, toMin, toMax) {
|
||||
// Compute the range of the data
|
||||
var fromRange = fromMax - fromMin,
|
||||
toRange = toMax - toMin,
|
||||
toValue;
|
||||
function remap(fromValue, fromMin, fromMax, toMin, toMax) {
|
||||
// Compute the range of the data
|
||||
var fromRange = fromMax - fromMin,
|
||||
toRange = toMax - toMin,
|
||||
toValue;
|
||||
|
||||
// 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;
|
||||
// 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
|
||||
toValue = (fromValue - fromMin) / fromRange;
|
||||
toValue = (toRange * toValue) + toMin;
|
||||
|
||||
return toValue;
|
||||
}
|
||||
|
||||
// (1) untranslate, (2) unscale, (3) rescale, (4) retranslate
|
||||
toValue = (fromValue - fromMin) / fromRange;
|
||||
toValue = (toRange * toValue) + toMin;
|
||||
|
||||
return toValue;
|
||||
}
|
||||
/**
|
||||
* Enhance Filter. Adjusts the colors so that they span the widest
|
||||
* possible range (ie 0-255). Performs w*h pixel reads and w*h pixel
|
||||
* writes.
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
Kinetic.Filters.Enhance = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nSubPixels = data.length,
|
||||
rMin = data[0], rMax = rMin, r,
|
||||
gMin = data[1], gMax = gMin, g,
|
||||
bMin = data[2], bMax = bMin, b,
|
||||
aMin = data[3], aMax = aMin,
|
||||
i;
|
||||
|
||||
// If we are not enhancing anything - don't do any computation
|
||||
var enhanceAmount = this.enhance();
|
||||
if( enhanceAmount === 0 ){ return; }
|
||||
|
||||
/**
|
||||
* Enhance Filter. Adjusts the colors so that they span the widest
|
||||
* possible range (ie 0-255). Performs w*h pixel reads and w*h pixel
|
||||
* writes.
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
Kinetic.Filters.Enhance = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nSubPixels = data.length,
|
||||
rMin = data[0], rMax = rMin, r,
|
||||
gMin = data[1], gMax = gMin, g,
|
||||
bMin = data[2], bMax = bMin, b,
|
||||
aMin = data[3], aMax = aMin, a,
|
||||
i;
|
||||
// 1st Pass - find the min and max for each channel:
|
||||
for (i = 0; i < nSubPixels; i += 4) {
|
||||
r = data[i + 0];
|
||||
if (r < rMin) { rMin = r; }
|
||||
else if (r > rMax) { rMax = r; }
|
||||
g = data[i + 1];
|
||||
if (g < gMin) { gMin = g; } else
|
||||
if (g > gMax) { gMax = g; }
|
||||
b = data[i + 2];
|
||||
if (b < bMin) { bMin = b; } else
|
||||
if (b > bMax) { bMax = b; }
|
||||
//a = data[i + 3];
|
||||
//if (a < aMin) { aMin = a; } else
|
||||
//if (a > aMax) { aMax = a; }
|
||||
}
|
||||
|
||||
// If we are not enhancing anything - don't do any computation
|
||||
var enhanceAmount = this.enhance();
|
||||
if( enhanceAmount === 0 ){ return; }
|
||||
// If there is only 1 level - don't remap
|
||||
if( rMax === rMin ){ rMax = 255; rMin = 0; }
|
||||
if( gMax === gMin ){ gMax = 255; gMin = 0; }
|
||||
if( bMax === bMin ){ bMax = 255; bMin = 0; }
|
||||
if( aMax === aMin ){ aMax = 255; aMin = 0; }
|
||||
|
||||
// 1st Pass - find the min and max for each channel:
|
||||
for (i = 0; i < nSubPixels; i += 4) {
|
||||
r = data[i + 0];
|
||||
if (r < rMin) { rMin = r; } else
|
||||
if (r > rMax) { rMax = r; }
|
||||
g = data[i + 1];
|
||||
if (g < gMin) { gMin = g; } else
|
||||
if (g > gMax) { gMax = g; }
|
||||
b = data[i + 2];
|
||||
if (b < bMin) { bMin = b; } else
|
||||
if (b > bMax) { bMax = b; }
|
||||
//a = data[i + 3];
|
||||
//if (a < aMin) { aMin = a; } else
|
||||
//if (a > aMax) { aMax = a; }
|
||||
}
|
||||
var rMid, rGoalMax,rGoalMin,
|
||||
gMid, gGoalMax,gGoalMin,
|
||||
bMid, bGoalMax,aGoalMin,
|
||||
aMid, aGoalMax,bGoalMin;
|
||||
|
||||
// If there is only 1 level - don't remap
|
||||
if( rMax === rMin ){ rMax = 255; rMin = 0; }
|
||||
if( gMax === gMin ){ gMax = 255; gMin = 0; }
|
||||
if( bMax === bMin ){ bMax = 255; bMin = 0; }
|
||||
if( aMax === aMin ){ aMax = 255; aMin = 0; }
|
||||
// If the enhancement is positive - stretch the histogram
|
||||
if ( enhanceAmount > 0 ){
|
||||
rGoalMax = rMax + enhanceAmount*(255-rMax);
|
||||
rGoalMin = rMin - enhanceAmount*(rMin-0);
|
||||
gGoalMax = gMax + enhanceAmount*(255-gMax);
|
||||
gGoalMin = gMin - enhanceAmount*(gMin-0);
|
||||
bGoalMax = bMax + enhanceAmount*(255-bMax);
|
||||
bGoalMin = bMin - enhanceAmount*(bMin-0);
|
||||
aGoalMax = aMax + enhanceAmount*(255-aMax);
|
||||
aGoalMin = aMin - enhanceAmount*(aMin-0);
|
||||
// If the enhancement is negative - compress the histogram
|
||||
} else {
|
||||
rMid = (rMax + rMin)*0.5;
|
||||
rGoalMax = rMax + enhanceAmount*(rMax-rMid);
|
||||
rGoalMin = rMin + enhanceAmount*(rMin-rMid);
|
||||
gMid = (gMax + gMin)*0.5;
|
||||
gGoalMax = gMax + enhanceAmount*(gMax-gMid);
|
||||
gGoalMin = gMin + enhanceAmount*(gMin-gMid);
|
||||
bMid = (bMax + bMin)*0.5;
|
||||
bGoalMax = bMax + enhanceAmount*(bMax-bMid);
|
||||
bGoalMin = bMin + enhanceAmount*(bMin-bMid);
|
||||
aMid = (aMax + aMin)*0.5;
|
||||
aGoalMax = aMax + enhanceAmount*(aMax-aMid);
|
||||
aGoalMin = aMin + enhanceAmount*(aMin-aMid);
|
||||
}
|
||||
|
||||
var rMid, rGoalMax,rGoalMin,
|
||||
gMid, gGoalMax,gGoalMin,
|
||||
bMid, bGoalMax,aGoalMin,
|
||||
aMid, aGoalMax,bGoalMin;
|
||||
// Pass 2 - remap everything, except the alpha
|
||||
for (i = 0; i < nSubPixels; i += 4) {
|
||||
data[i + 0] = remap(data[i + 0], rMin, rMax, rGoalMin, rGoalMax);
|
||||
data[i + 1] = remap(data[i + 1], gMin, gMax, gGoalMin, gGoalMax);
|
||||
data[i + 2] = remap(data[i + 2], bMin, bMax, bGoalMin, bGoalMax);
|
||||
//data[i + 3] = remap(data[i + 3], aMin, aMax, aGoalMin, aGoalMax);
|
||||
}
|
||||
};
|
||||
|
||||
// If the enhancement is positive - stretch the histogram
|
||||
if( enhanceAmount > 0 ){
|
||||
rGoalMax = rMax + enhanceAmount*(255-rMax);
|
||||
rGoalMin = rMin - enhanceAmount*(rMin-0);
|
||||
gGoalMax = gMax + enhanceAmount*(255-gMax);
|
||||
gGoalMin = gMin - enhanceAmount*(gMin-0);
|
||||
bGoalMax = bMax + enhanceAmount*(255-bMax);
|
||||
bGoalMin = bMin - enhanceAmount*(bMin-0);
|
||||
aGoalMax = aMax + enhanceAmount*(255-aMax);
|
||||
aGoalMin = aMin - enhanceAmount*(aMin-0);
|
||||
// If the enhancement is negative - compress the histogram
|
||||
}else{
|
||||
rMid = (rMax + rMin)*0.5;
|
||||
rGoalMax = rMax + enhanceAmount*(rMax-rMid);
|
||||
rGoalMin = rMin + enhanceAmount*(rMin-rMid);
|
||||
gMid = (gMax + gMin)*0.5;
|
||||
gGoalMax = gMax + enhanceAmount*(gMax-gMid);
|
||||
gGoalMin = gMin + enhanceAmount*(gMin-gMid);
|
||||
bMid = (bMax + bMin)*0.5;
|
||||
bGoalMax = bMax + enhanceAmount*(bMax-bMid);
|
||||
bGoalMin = bMin + enhanceAmount*(bMin-bMid);
|
||||
aMid = (aMax + aMin)*0.5;
|
||||
aGoalMax = aMax + enhanceAmount*(aMax-aMid);
|
||||
aGoalMin = aMin + enhanceAmount*(aMin-aMid);
|
||||
}
|
||||
|
||||
// Pass 2 - remap everything, except the alpha
|
||||
for (i = 0; i < nSubPixels; i += 4) {
|
||||
data[i + 0] = remap(data[i + 0], rMin, rMax, rGoalMin, rGoalMax);
|
||||
data[i + 1] = remap(data[i + 1], gMin, gMax, gGoalMin, gGoalMax);
|
||||
data[i + 2] = remap(data[i + 2], bMin, bMax, bGoalMin, bGoalMax);
|
||||
//data[i + 3] = remap(data[i + 3], aMin, aMax, aGoalMin, aGoalMax);
|
||||
}
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'enhance', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'enhance', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
/**
|
||||
* get/set enhance
|
||||
|
||||
@@ -1,89 +1,89 @@
|
||||
(function () {
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'hue', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv hue in degrees
|
||||
* @name hue
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} hue value between 0 and 359
|
||||
* @returns {Number}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'hue', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv hue in degrees
|
||||
* @name hue
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} hue value between 0 and 359
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'saturation', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv saturation
|
||||
* @name saturation
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'saturation', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv saturation
|
||||
* @name saturation
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'luminance', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsl luminance
|
||||
* @name value
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'luminance', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsl luminance
|
||||
* @name value
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
/**
|
||||
* HSL Filter. Adjusts the hue, saturation and luminance (or lightness)
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
/**
|
||||
* HSL Filter. Adjusts the hue, saturation and luminance (or lightness)
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
|
||||
Kinetic.Filters.HSL = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nPixels = data.length,
|
||||
v = 1,
|
||||
s = Math.pow(2,this.saturation()),
|
||||
h = Math.abs((this.hue()) + 360) % 360,
|
||||
l = this.luminance()*127,
|
||||
i;
|
||||
Kinetic.Filters.HSL = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nPixels = data.length,
|
||||
v = 1,
|
||||
s = Math.pow(2,this.saturation()),
|
||||
h = Math.abs((this.hue()) + 360) % 360,
|
||||
l = this.luminance()*127,
|
||||
i;
|
||||
|
||||
// Basis for the technique used:
|
||||
// http://beesbuzz.biz/code/hsv_color_transforms.php
|
||||
// V is the value multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// S is the saturation multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// H is the hue shift in degrees (0 to 360)
|
||||
// vsu = V*S*cos(H*PI/180);
|
||||
// vsw = V*S*sin(H*PI/180);
|
||||
//[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R]
|
||||
//[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G]
|
||||
//[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B]
|
||||
// Basis for the technique used:
|
||||
// http://beesbuzz.biz/code/hsv_color_transforms.php
|
||||
// V is the value multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// S is the saturation multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// H is the hue shift in degrees (0 to 360)
|
||||
// vsu = V*S*cos(H*PI/180);
|
||||
// vsw = V*S*sin(H*PI/180);
|
||||
//[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R]
|
||||
//[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G]
|
||||
//[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B]
|
||||
|
||||
// Precompute the values in the matrix:
|
||||
var vsu = v*s*Math.cos(h*Math.PI/180),
|
||||
vsw = v*s*Math.sin(h*Math.PI/180);
|
||||
// (result spot)(source spot)
|
||||
var rr = 0.299*v+0.701*vsu+0.167*vsw,
|
||||
rg = 0.587*v-0.587*vsu+0.330*vsw,
|
||||
rb = 0.114*v-0.114*vsu-0.497*vsw;
|
||||
var gr = 0.299*v-0.299*vsu-0.328*vsw,
|
||||
gg = 0.587*v+0.413*vsu+0.035*vsw,
|
||||
gb = 0.114*v-0.114*vsu+0.293*vsw;
|
||||
var br = 0.299*v-0.300*vsu+1.250*vsw,
|
||||
bg = 0.587*v-0.586*vsu-1.050*vsw,
|
||||
bb = 0.114*v+0.886*vsu-0.200*vsw;
|
||||
// Precompute the values in the matrix:
|
||||
var vsu = v*s*Math.cos(h*Math.PI/180),
|
||||
vsw = v*s*Math.sin(h*Math.PI/180);
|
||||
// (result spot)(source spot)
|
||||
var rr = 0.299*v+0.701*vsu+0.167*vsw,
|
||||
rg = 0.587*v-0.587*vsu+0.330*vsw,
|
||||
rb = 0.114*v-0.114*vsu-0.497*vsw;
|
||||
var gr = 0.299*v-0.299*vsu-0.328*vsw,
|
||||
gg = 0.587*v+0.413*vsu+0.035*vsw,
|
||||
gb = 0.114*v-0.114*vsu+0.293*vsw;
|
||||
var br = 0.299*v-0.300*vsu+1.250*vsw,
|
||||
bg = 0.587*v-0.586*vsu-1.050*vsw,
|
||||
bb = 0.114*v+0.886*vsu-0.200*vsw;
|
||||
|
||||
var r,g,b,a;
|
||||
var r,g,b,a;
|
||||
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
r = data[i+0];
|
||||
g = data[i+1];
|
||||
b = data[i+2];
|
||||
a = data[i+3];
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
r = data[i+0];
|
||||
g = data[i+1];
|
||||
b = data[i+2];
|
||||
a = data[i+3];
|
||||
|
||||
data[i+0] = rr*r + rg*g + rb*b + l;
|
||||
data[i+1] = gr*r + gg*g + gb*b + l;
|
||||
data[i+2] = br*r + bg*g + bb*b + l;
|
||||
data[i+3] = a; // alpha
|
||||
}
|
||||
};
|
||||
data[i+0] = rr*r + rg*g + rb*b + l;
|
||||
data[i+1] = gr*r + gg*g + gb*b + l;
|
||||
data[i+2] = br*r + bg*g + bb*b + l;
|
||||
data[i+3] = a; // alpha
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,90 +1,90 @@
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* HSV Filter. Adjusts the hue, saturation and value
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
/**
|
||||
* HSV Filter. Adjusts the hue, saturation and value
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
|
||||
Kinetic.Filters.HSV = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nPixels = data.length,
|
||||
v = Math.pow(2,this.value()),
|
||||
s = Math.pow(2,this.saturation()),
|
||||
h = Math.abs((this.hue()) + 360) % 360,
|
||||
i;
|
||||
Kinetic.Filters.HSV = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nPixels = data.length,
|
||||
v = Math.pow(2,this.value()),
|
||||
s = Math.pow(2,this.saturation()),
|
||||
h = Math.abs((this.hue()) + 360) % 360,
|
||||
i;
|
||||
|
||||
// Basis for the technique used:
|
||||
// http://beesbuzz.biz/code/hsv_color_transforms.php
|
||||
// V is the value multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// S is the saturation multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// H is the hue shift in degrees (0 to 360)
|
||||
// vsu = V*S*cos(H*PI/180);
|
||||
// vsw = V*S*sin(H*PI/180);
|
||||
//[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R]
|
||||
//[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G]
|
||||
//[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B]
|
||||
// Basis for the technique used:
|
||||
// http://beesbuzz.biz/code/hsv_color_transforms.php
|
||||
// V is the value multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// S is the saturation multiplier (1 for none, 2 for double, 0.5 for half)
|
||||
// H is the hue shift in degrees (0 to 360)
|
||||
// vsu = V*S*cos(H*PI/180);
|
||||
// vsw = V*S*sin(H*PI/180);
|
||||
//[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R]
|
||||
//[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G]
|
||||
//[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B]
|
||||
|
||||
// Precompute the values in the matrix:
|
||||
var vsu = v*s*Math.cos(h*Math.PI/180),
|
||||
vsw = v*s*Math.sin(h*Math.PI/180);
|
||||
// (result spot)(source spot)
|
||||
var rr = 0.299*v+0.701*vsu+0.167*vsw,
|
||||
rg = 0.587*v-0.587*vsu+0.330*vsw,
|
||||
rb = 0.114*v-0.114*vsu-0.497*vsw;
|
||||
var gr = 0.299*v-0.299*vsu-0.328*vsw,
|
||||
gg = 0.587*v+0.413*vsu+0.035*vsw,
|
||||
gb = 0.114*v-0.114*vsu+0.293*vsw;
|
||||
var br = 0.299*v-0.300*vsu+1.250*vsw,
|
||||
bg = 0.587*v-0.586*vsu-1.050*vsw,
|
||||
bb = 0.114*v+0.886*vsu-0.200*vsw;
|
||||
// Precompute the values in the matrix:
|
||||
var vsu = v*s*Math.cos(h*Math.PI/180),
|
||||
vsw = v*s*Math.sin(h*Math.PI/180);
|
||||
// (result spot)(source spot)
|
||||
var rr = 0.299*v+0.701*vsu+0.167*vsw,
|
||||
rg = 0.587*v-0.587*vsu+0.330*vsw,
|
||||
rb = 0.114*v-0.114*vsu-0.497*vsw;
|
||||
var gr = 0.299*v-0.299*vsu-0.328*vsw,
|
||||
gg = 0.587*v+0.413*vsu+0.035*vsw,
|
||||
gb = 0.114*v-0.114*vsu+0.293*vsw;
|
||||
var br = 0.299*v-0.300*vsu+1.250*vsw,
|
||||
bg = 0.587*v-0.586*vsu-1.050*vsw,
|
||||
bb = 0.114*v+0.886*vsu-0.200*vsw;
|
||||
|
||||
var r,g,b,a;
|
||||
var r,g,b,a;
|
||||
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
r = data[i+0];
|
||||
g = data[i+1];
|
||||
b = data[i+2];
|
||||
a = data[i+3];
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
r = data[i+0];
|
||||
g = data[i+1];
|
||||
b = data[i+2];
|
||||
a = data[i+3];
|
||||
|
||||
data[i+0] = rr*r + rg*g + rb*b;
|
||||
data[i+1] = gr*r + gg*g + gb*b;
|
||||
data[i+2] = br*r + bg*g + bb*b;
|
||||
data[i+3] = a; // alpha
|
||||
}
|
||||
data[i+0] = rr*r + rg*g + rb*b;
|
||||
data[i+1] = gr*r + gg*g + gb*b;
|
||||
data[i+2] = br*r + bg*g + bb*b;
|
||||
data[i+3] = a; // alpha
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'hue', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv hue in degrees
|
||||
* @name hue
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} hue value between 0 and 359
|
||||
* @returns {Number}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'hue', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv hue in degrees
|
||||
* @name hue
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} hue value between 0 and 359
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'saturation', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv saturation
|
||||
* @name saturation
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'saturation', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv saturation
|
||||
* @name saturation
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'value', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv value
|
||||
* @name value
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'value', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set hsv value
|
||||
* @name value
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc..
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
})();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*jshint newcap:false */
|
||||
(function () {
|
||||
|
||||
/*
|
||||
@@ -16,244 +17,245 @@
|
||||
* default is in the middle
|
||||
*/
|
||||
|
||||
var ToPolar = function(src,dst,opt){
|
||||
var ToPolar = function(src,dst,opt){
|
||||
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = opt.polarCenterX || xSize/2,
|
||||
yMid = opt.polarCenterY || ySize/2,
|
||||
i, m, x, y, k, tmp, r=0,g=0,b=0,a=0;
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = opt.polarCenterX || xSize/2,
|
||||
yMid = opt.polarCenterY || ySize/2,
|
||||
i, x, y, r=0,g=0,b=0,a=0;
|
||||
|
||||
// Find the largest radius
|
||||
var rad, rMax = Math.sqrt( xMid*xMid + yMid*yMid );
|
||||
x = xSize - xMid;
|
||||
y = ySize - yMid;
|
||||
rad = Math.sqrt( x*x + y*y );
|
||||
rMax = (rad > rMax)?rad:rMax;
|
||||
// Find the largest radius
|
||||
var rad, rMax = Math.sqrt( xMid*xMid + yMid*yMid );
|
||||
x = xSize - xMid;
|
||||
y = ySize - yMid;
|
||||
rad = Math.sqrt( x*x + y*y );
|
||||
rMax = (rad > rMax)?rad:rMax;
|
||||
|
||||
// We'll be uisng y as the radius, and x as the angle (theta=t)
|
||||
var rSize = ySize,
|
||||
tSize = xSize,
|
||||
radius, theta;
|
||||
// We'll be uisng y as the radius, and x as the angle (theta=t)
|
||||
var rSize = ySize,
|
||||
tSize = xSize,
|
||||
radius, theta;
|
||||
|
||||
// We want to cover all angles (0-360) and we need to convert to
|
||||
// radians (*PI/180)
|
||||
var conversion = 360/tSize*Math.PI/180, sin, cos;
|
||||
// We want to cover all angles (0-360) and we need to convert to
|
||||
// radians (*PI/180)
|
||||
var conversion = 360/tSize*Math.PI/180, sin, cos;
|
||||
|
||||
var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale;
|
||||
// var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale;
|
||||
|
||||
for( theta=0; theta<tSize; theta+=1 ){
|
||||
sin = Math.sin(theta*conversion);
|
||||
cos = Math.cos(theta*conversion);
|
||||
for( radius=0; radius<rSize; radius+=1 ){
|
||||
x = Math.floor(xMid+rMax*radius/rSize*cos);
|
||||
y = Math.floor(yMid+rMax*radius/rSize*sin);
|
||||
i = (y*xSize + x)*4;
|
||||
r = srcPixels[i+0];
|
||||
g = srcPixels[i+1];
|
||||
b = srcPixels[i+2];
|
||||
a = srcPixels[i+3];
|
||||
for( theta=0; theta<tSize; theta+=1 ){
|
||||
sin = Math.sin(theta*conversion);
|
||||
cos = Math.cos(theta*conversion);
|
||||
for( radius=0; radius<rSize; radius+=1 ){
|
||||
x = Math.floor(xMid+rMax*radius/rSize*cos);
|
||||
y = Math.floor(yMid+rMax*radius/rSize*sin);
|
||||
i = (y*xSize + x)*4;
|
||||
r = srcPixels[i+0];
|
||||
g = srcPixels[i+1];
|
||||
b = srcPixels[i+2];
|
||||
a = srcPixels[i+3];
|
||||
|
||||
// Store it
|
||||
//i = (theta * xSize + radius) * 4;
|
||||
i = (theta + radius*xSize) * 4;
|
||||
dstPixels[i+0] = r;
|
||||
dstPixels[i+1] = g;
|
||||
dstPixels[i+2] = b;
|
||||
dstPixels[i+3] = a;
|
||||
// Store it
|
||||
//i = (theta * xSize + radius) * 4;
|
||||
i = (theta + radius*xSize) * 4;
|
||||
dstPixels[i+0] = r;
|
||||
dstPixels[i+1] = g;
|
||||
dstPixels[i+2] = b;
|
||||
dstPixels[i+3] = a;
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* FromPolar Filter. Converts image data from polar coordinates back to rectangular.
|
||||
* Performs w*h*4 pixel reads and w*h pixel writes.
|
||||
* @function
|
||||
* @author ippo615
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {ImageData} src, the source image data (what will be transformed)
|
||||
* @param {ImageData} dst, the destination image data (where it will be saved)
|
||||
* @param {Object} opt
|
||||
* @param {Number} [opt.polarCenterX] horizontal location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarCenterY] vertical location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarRotation] amount to rotate the image counterclockwis,
|
||||
* 0 is no rotation, 360 degrees is a full rotation
|
||||
*/
|
||||
|
||||
var FromPolar = function(src,dst,opt){
|
||||
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = opt.polarCenterX || xSize/2,
|
||||
yMid = opt.polarCenterY || ySize/2,
|
||||
i, m, x, y, dx, dy, k, tmp, r=0,g=0,b=0,a=0;
|
||||
|
||||
|
||||
// Find the largest radius
|
||||
var rad, rMax = Math.sqrt( xMid*xMid + yMid*yMid );
|
||||
x = xSize - xMid;
|
||||
y = ySize - yMid;
|
||||
rad = Math.sqrt( x*x + y*y );
|
||||
rMax = (rad > rMax)?rad:rMax;
|
||||
|
||||
// We'll be uisng x as the radius, and y as the angle (theta=t)
|
||||
var rSize = ySize,
|
||||
tSize = xSize,
|
||||
radius, theta,
|
||||
phaseShift = opt.polarRotation || 0;
|
||||
|
||||
// We need to convert to degrees and we need to make sure
|
||||
// it's between (0-360)
|
||||
// var conversion = tSize/360*180/Math.PI;
|
||||
var conversion = tSize/360*180/Math.PI;
|
||||
|
||||
var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale;
|
||||
|
||||
for( x=0; x<xSize; x+=1 ){
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
dx = x - xMid;
|
||||
dy = y - yMid;
|
||||
radius = Math.sqrt(dx*dx + dy*dy)*rSize/rMax;
|
||||
theta = (Math.atan2(dy,dx)*180/Math.PI + 360 + phaseShift)%360;
|
||||
theta = theta*tSize/360;
|
||||
x1 = Math.floor(theta);
|
||||
y1 = Math.floor(radius);
|
||||
i = (y1*xSize + x1)*4;
|
||||
r = srcPixels[i+0];
|
||||
g = srcPixels[i+1];
|
||||
b = srcPixels[i+2];
|
||||
a = srcPixels[i+3];
|
||||
|
||||
// Store it
|
||||
i = (y*xSize + x)*4;
|
||||
dstPixels[i+0] = r;
|
||||
dstPixels[i+1] = g;
|
||||
dstPixels[i+2] = b;
|
||||
dstPixels[i+3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//Kinetic.Filters.ToPolar = Kinetic.Util._FilterWrapDoubleBuffer(ToPolar);
|
||||
//Kinetic.Filters.FromPolar = Kinetic.Util._FilterWrapDoubleBuffer(FromPolar);
|
||||
|
||||
// create a temporary canvas for working - shared between multiple calls
|
||||
var tempCanvas = document.createElement('canvas');
|
||||
|
||||
/*
|
||||
* Kaleidoscope Filter.
|
||||
* @function
|
||||
* @author ippo615
|
||||
* @memberof Kinetic.Filters
|
||||
*/
|
||||
Kinetic.Filters.Kaleidoscope = function(imageData){
|
||||
var xSize = imageData.width,
|
||||
ySize = imageData.height;
|
||||
var power = Math.round( this.kaleidoscopePower() );
|
||||
var angle = Math.round( this.kaleidoscopeAngle() );
|
||||
var offset = Math.floor(xSize*(angle%360)/360);
|
||||
|
||||
if( power < 1 ){return;}
|
||||
|
||||
// Work with our shared buffer canvas
|
||||
tempCanvas.width = xSize;
|
||||
tempCanvas.height = ySize;
|
||||
var scratchData = tempCanvas.getContext('2d').getImageData(0,0,xSize,ySize);
|
||||
|
||||
// Convert thhe original to polar coordinates
|
||||
ToPolar( imageData, scratchData, {
|
||||
polarCenterX:xSize/2,
|
||||
polarCenterY:ySize/2
|
||||
});
|
||||
|
||||
// Determine how big each section will be, if it's too small
|
||||
// make it bigger
|
||||
var minSectionSize = xSize / Math.pow(2,power);
|
||||
while( minSectionSize <= 8){
|
||||
minSectionSize = minSectionSize*2;
|
||||
power -= 1;
|
||||
}
|
||||
minSectionSize = Math.ceil(minSectionSize);
|
||||
var sectionSize = minSectionSize;
|
||||
|
||||
// Copy the offset region to 0
|
||||
// Depending on the size of filter and location of the offset we may need
|
||||
// to copy the section backwards to prevent it from rewriting itself
|
||||
var xStart = 0,
|
||||
xEnd = sectionSize,
|
||||
xDelta = 1;
|
||||
if( offset+minSectionSize > xSize ){
|
||||
xStart = sectionSize;
|
||||
xEnd = 0;
|
||||
xDelta = -1;
|
||||
}
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
for( x=xStart; x !== xEnd; x+=xDelta ){
|
||||
xoff = Math.round(x+offset)%xSize;
|
||||
srcPos = (xSize*y+xoff)*4;
|
||||
r = scratchData.data[srcPos+0];
|
||||
g = scratchData.data[srcPos+1];
|
||||
b = scratchData.data[srcPos+2];
|
||||
a = scratchData.data[srcPos+3];
|
||||
dstPos = (xSize*y+x)*4;
|
||||
scratchData.data[dstPos+0] = r;
|
||||
scratchData.data[dstPos+1] = g;
|
||||
scratchData.data[dstPos+2] = b;
|
||||
scratchData.data[dstPos+3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the actual effect
|
||||
var x,y,xoff,i, r,g,b,a, srcPos, dstPos;
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
sectionSize = Math.floor( minSectionSize );
|
||||
for( i=0; i<power; i+=1 ){
|
||||
for( x=0; x<sectionSize+1; x+=1 ){
|
||||
srcPos = (xSize*y+x)*4;
|
||||
r = scratchData.data[srcPos+0];
|
||||
g = scratchData.data[srcPos+1];
|
||||
b = scratchData.data[srcPos+2];
|
||||
a = scratchData.data[srcPos+3];
|
||||
dstPos = (xSize*y+sectionSize*2-x-1)*4;
|
||||
scratchData.data[dstPos+0] = r;
|
||||
scratchData.data[dstPos+1] = g;
|
||||
scratchData.data[dstPos+2] = b;
|
||||
scratchData.data[dstPos+3] = a;
|
||||
}
|
||||
}
|
||||
sectionSize *= 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Convert back from polar coordinates
|
||||
FromPolar(scratchData,imageData,{polarRotation:0});
|
||||
};
|
||||
/*
|
||||
* FromPolar Filter. Converts image data from polar coordinates back to rectangular.
|
||||
* Performs w*h*4 pixel reads and w*h pixel writes.
|
||||
* @function
|
||||
* @author ippo615
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {ImageData} src, the source image data (what will be transformed)
|
||||
* @param {ImageData} dst, the destination image data (where it will be saved)
|
||||
* @param {Object} opt
|
||||
* @param {Number} [opt.polarCenterX] horizontal location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarCenterY] vertical location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarRotation] amount to rotate the image counterclockwis,
|
||||
* 0 is no rotation, 360 degrees is a full rotation
|
||||
*/
|
||||
|
||||
/**
|
||||
* get/set kaleidoscope power
|
||||
* @name kaleidoscopePower
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} power of kaleidoscope
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'kaleidoscopePower', 2, null, Kinetic.Factory.afterSetFilter);
|
||||
var FromPolar = function(src,dst,opt){
|
||||
|
||||
/**
|
||||
* get/set kaleidoscope angle
|
||||
* @name kaleidoscopeAngle
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} degrees
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'kaleidoscopeAngle', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = opt.polarCenterX || xSize/2,
|
||||
yMid = opt.polarCenterY || ySize/2,
|
||||
i, x, y, dx, dy, r=0,g=0,b=0,a=0;
|
||||
|
||||
|
||||
// Find the largest radius
|
||||
var rad, rMax = Math.sqrt( xMid*xMid + yMid*yMid );
|
||||
x = xSize - xMid;
|
||||
y = ySize - yMid;
|
||||
rad = Math.sqrt( x*x + y*y );
|
||||
rMax = (rad > rMax)?rad:rMax;
|
||||
|
||||
// We'll be uisng x as the radius, and y as the angle (theta=t)
|
||||
var rSize = ySize,
|
||||
tSize = xSize,
|
||||
radius, theta,
|
||||
phaseShift = opt.polarRotation || 0;
|
||||
|
||||
// We need to convert to degrees and we need to make sure
|
||||
// it's between (0-360)
|
||||
// var conversion = tSize/360*180/Math.PI;
|
||||
//var conversion = tSize/360*180/Math.PI;
|
||||
|
||||
var x1, y1;
|
||||
|
||||
for( x=0; x<xSize; x+=1 ){
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
dx = x - xMid;
|
||||
dy = y - yMid;
|
||||
radius = Math.sqrt(dx*dx + dy*dy)*rSize/rMax;
|
||||
theta = (Math.atan2(dy,dx)*180/Math.PI + 360 + phaseShift)%360;
|
||||
theta = theta*tSize/360;
|
||||
x1 = Math.floor(theta);
|
||||
y1 = Math.floor(radius);
|
||||
i = (y1*xSize + x1)*4;
|
||||
r = srcPixels[i+0];
|
||||
g = srcPixels[i+1];
|
||||
b = srcPixels[i+2];
|
||||
a = srcPixels[i+3];
|
||||
|
||||
// Store it
|
||||
i = (y*xSize + x)*4;
|
||||
dstPixels[i+0] = r;
|
||||
dstPixels[i+1] = g;
|
||||
dstPixels[i+2] = b;
|
||||
dstPixels[i+3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//Kinetic.Filters.ToPolar = Kinetic.Util._FilterWrapDoubleBuffer(ToPolar);
|
||||
//Kinetic.Filters.FromPolar = Kinetic.Util._FilterWrapDoubleBuffer(FromPolar);
|
||||
|
||||
// create a temporary canvas for working - shared between multiple calls
|
||||
var tempCanvas = document.createElement('canvas');
|
||||
|
||||
/*
|
||||
* Kaleidoscope Filter.
|
||||
* @function
|
||||
* @author ippo615
|
||||
* @memberof Kinetic.Filters
|
||||
*/
|
||||
Kinetic.Filters.Kaleidoscope = function(imageData){
|
||||
var xSize = imageData.width,
|
||||
ySize = imageData.height;
|
||||
|
||||
var x,y,xoff,i, r,g,b,a, srcPos, dstPos;
|
||||
var power = Math.round( this.kaleidoscopePower() );
|
||||
var angle = Math.round( this.kaleidoscopeAngle() );
|
||||
var offset = Math.floor(xSize*(angle%360)/360);
|
||||
|
||||
if( power < 1 ){return;}
|
||||
|
||||
// Work with our shared buffer canvas
|
||||
tempCanvas.width = xSize;
|
||||
tempCanvas.height = ySize;
|
||||
var scratchData = tempCanvas.getContext('2d').getImageData(0,0,xSize,ySize);
|
||||
|
||||
// Convert thhe original to polar coordinates
|
||||
ToPolar( imageData, scratchData, {
|
||||
polarCenterX:xSize/2,
|
||||
polarCenterY:ySize/2
|
||||
});
|
||||
|
||||
// Determine how big each section will be, if it's too small
|
||||
// make it bigger
|
||||
var minSectionSize = xSize / Math.pow(2,power);
|
||||
while( minSectionSize <= 8){
|
||||
minSectionSize = minSectionSize*2;
|
||||
power -= 1;
|
||||
}
|
||||
minSectionSize = Math.ceil(minSectionSize);
|
||||
var sectionSize = minSectionSize;
|
||||
|
||||
// Copy the offset region to 0
|
||||
// Depending on the size of filter and location of the offset we may need
|
||||
// to copy the section backwards to prevent it from rewriting itself
|
||||
var xStart = 0,
|
||||
xEnd = sectionSize,
|
||||
xDelta = 1;
|
||||
if( offset+minSectionSize > xSize ){
|
||||
xStart = sectionSize;
|
||||
xEnd = 0;
|
||||
xDelta = -1;
|
||||
}
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
for( x=xStart; x !== xEnd; x+=xDelta ){
|
||||
xoff = Math.round(x+offset)%xSize;
|
||||
srcPos = (xSize*y+xoff)*4;
|
||||
r = scratchData.data[srcPos+0];
|
||||
g = scratchData.data[srcPos+1];
|
||||
b = scratchData.data[srcPos+2];
|
||||
a = scratchData.data[srcPos+3];
|
||||
dstPos = (xSize*y+x)*4;
|
||||
scratchData.data[dstPos+0] = r;
|
||||
scratchData.data[dstPos+1] = g;
|
||||
scratchData.data[dstPos+2] = b;
|
||||
scratchData.data[dstPos+3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the actual effect
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
sectionSize = Math.floor( minSectionSize );
|
||||
for( i=0; i<power; i+=1 ){
|
||||
for( x=0; x<sectionSize+1; x+=1 ){
|
||||
srcPos = (xSize*y+x)*4;
|
||||
r = scratchData.data[srcPos+0];
|
||||
g = scratchData.data[srcPos+1];
|
||||
b = scratchData.data[srcPos+2];
|
||||
a = scratchData.data[srcPos+3];
|
||||
dstPos = (xSize*y+sectionSize*2-x-1)*4;
|
||||
scratchData.data[dstPos+0] = r;
|
||||
scratchData.data[dstPos+1] = g;
|
||||
scratchData.data[dstPos+2] = b;
|
||||
scratchData.data[dstPos+3] = a;
|
||||
}
|
||||
sectionSize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert back from polar coordinates
|
||||
FromPolar(scratchData,imageData,{polarRotation:0});
|
||||
};
|
||||
|
||||
/**
|
||||
* get/set kaleidoscope power
|
||||
* @name kaleidoscopePower
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} power of kaleidoscope
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'kaleidoscopePower', 2, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
/**
|
||||
* get/set kaleidoscope angle
|
||||
* @name kaleidoscopeAngle
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} degrees
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'kaleidoscopeAngle', 0, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
})();
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var rgbv_se = pixelAt(idata, idata.width - 1, idata.height - 1);
|
||||
|
||||
|
||||
var thres = threshold || 10;
|
||||
var thres = threshold || 10;
|
||||
if (rgbDistance(rgbv_no, rgbv_ne) < thres && rgbDistance(rgbv_ne, rgbv_se) < thres && rgbDistance(rgbv_se, rgbv_so) < thres && rgbDistance(rgbv_so, rgbv_no) < thres) {
|
||||
|
||||
// Mean color
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* Noise Filter. Randomly adds or substracts to the color channels
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imagedata
|
||||
* @author ippo615
|
||||
*/
|
||||
Kinetic.Filters.Noise = function (imageData) {
|
||||
var amount = this.noise() * 255,
|
||||
data = imageData.data,
|
||||
nPixels = data.length,
|
||||
half = amount / 2,
|
||||
i;
|
||||
/**
|
||||
* Noise Filter. Randomly adds or substracts to the color channels
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imagedata
|
||||
* @author ippo615
|
||||
*/
|
||||
Kinetic.Filters.Noise = function (imageData) {
|
||||
var amount = this.noise() * 255,
|
||||
data = imageData.data,
|
||||
nPixels = data.length,
|
||||
half = amount / 2,
|
||||
i;
|
||||
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
data[i + 0] += half - 2 * half * Math.random();
|
||||
data[i + 1] += half - 2 * half * Math.random();
|
||||
data[i + 2] += half - 2 * half * Math.random();
|
||||
}
|
||||
};
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
data[i + 0] += half - 2 * half * Math.random();
|
||||
data[i + 1] += half - 2 * half * Math.random();
|
||||
data[i + 2] += half - 2 * half * Math.random();
|
||||
}
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'noise', 0.2, null, Kinetic.Factory.afterSetFilter);
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'noise', 0.2, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
/**
|
||||
* get/set noise amount. Must be a value between 0 and 1
|
||||
* @name noise
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} noise
|
||||
* @returns {Number}
|
||||
*/
|
||||
/**
|
||||
* get/set noise amount. Must be a value between 0 and 1
|
||||
* @name noise
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} noise
|
||||
* @returns {Number}
|
||||
*/
|
||||
})();
|
||||
|
||||
@@ -1,89 +1,88 @@
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* Pixelate Filter. Averages groups of pixels and redraws
|
||||
* them as larger pixels
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
/**
|
||||
* Pixelate Filter. Averages groups of pixels and redraws
|
||||
* them as larger pixels
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
|
||||
Kinetic.Filters.Pixelate = function (imageData) {
|
||||
Kinetic.Filters.Pixelate = function (imageData) {
|
||||
|
||||
var pixelSize = Math.ceil(this.pixelSize()),
|
||||
width = imageData.width,
|
||||
height = imageData.height,
|
||||
imageData = imageData.data,
|
||||
x, y, i,
|
||||
pixelsPerBin = pixelSize * pixelSize,
|
||||
red, green, blue, alpha,
|
||||
nBinsX = Math.ceil(width / pixelSize),
|
||||
nBinsY = Math.ceil(height / pixelSize),
|
||||
xBinStart, xBinEnd, yBinStart, yBinEnd,
|
||||
xBin, yBin, pixelsInBin;
|
||||
var pixelSize = Math.ceil(this.pixelSize()),
|
||||
width = imageData.width,
|
||||
height = imageData.height,
|
||||
x, y, i,
|
||||
//pixelsPerBin = pixelSize * pixelSize,
|
||||
red, green, blue, alpha,
|
||||
nBinsX = Math.ceil(width / pixelSize),
|
||||
nBinsY = Math.ceil(height / pixelSize),
|
||||
xBinStart, xBinEnd, yBinStart, yBinEnd,
|
||||
xBin, yBin, pixelsInBin;
|
||||
imageData = imageData.data;
|
||||
|
||||
for (xBin = 0; xBin < nBinsX; xBin += 1) {
|
||||
for (yBin = 0; yBin < nBinsY; yBin += 1) {
|
||||
for (xBin = 0; xBin < nBinsX; xBin += 1) {
|
||||
for (yBin = 0; yBin < nBinsY; yBin += 1) {
|
||||
|
||||
// Initialize the color accumlators to 0
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
alpha = 0;
|
||||
|
||||
// Determine which pixels are included in this bin
|
||||
xBinStart = xBin * pixelSize;
|
||||
xBinEnd = xBinStart + pixelSize;
|
||||
yBinStart = yBin * pixelSize;
|
||||
yBinEnd = yBinStart + pixelSize;
|
||||
|
||||
// Add all of the pixels to this bin!
|
||||
pixelsInBin = 0;
|
||||
for (x = xBinStart; x < xBinEnd; x += 1) {
|
||||
if( x >= width ){ continue; }
|
||||
for (y = yBinStart; y < yBinEnd; y += 1) {
|
||||
if( y >= height ){ continue; }
|
||||
i = (width * y + x) * 4;
|
||||
red += imageData[i + 0];
|
||||
green += imageData[i + 1];
|
||||
blue += imageData[i + 2];
|
||||
alpha += imageData[i + 3];
|
||||
pixelsInBin += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the channels are between 0-255
|
||||
red = red / pixelsInBin;
|
||||
green = green / pixelsInBin;
|
||||
blue = blue / pixelsInBin;
|
||||
|
||||
// Draw this bin
|
||||
for (x = xBinStart; x < xBinEnd; x += 1) {
|
||||
if( x >= width ){ continue; }
|
||||
for (y = yBinStart; y < yBinEnd; y += 1) {
|
||||
if( y >= height ){ continue; }
|
||||
i = (width * y + x) * 4;
|
||||
imageData[i + 0] = red;
|
||||
imageData[i + 1] = green;
|
||||
imageData[i + 2] = blue;
|
||||
imageData[i + 3] = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the color accumlators to 0
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
alpha = 0;
|
||||
};
|
||||
|
||||
// Determine which pixels are included in this bin
|
||||
xBinStart = xBin * pixelSize;
|
||||
xBinEnd = xBinStart + pixelSize;
|
||||
yBinStart = yBin * pixelSize;
|
||||
yBinEnd = yBinStart + pixelSize;
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'pixelSize', 8, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
// Add all of the pixels to this bin!
|
||||
pixelsInBin = 0;
|
||||
for (x = xBinStart; x < xBinEnd; x += 1) {
|
||||
if( x >= width ){ continue; }
|
||||
for (y = yBinStart; y < yBinEnd; y += 1) {
|
||||
if( y >= height ){ continue; }
|
||||
i = (width * y + x) * 4;
|
||||
red += imageData[i + 0];
|
||||
green += imageData[i + 1];
|
||||
blue += imageData[i + 2];
|
||||
alpha += imageData[i + 3];
|
||||
pixelsInBin += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the channels are between 0-255
|
||||
red = red / pixelsInBin;
|
||||
green = green / pixelsInBin;
|
||||
blue = blue / pixelsInBin;
|
||||
alphas = alpha / pixelsInBin;
|
||||
|
||||
// Draw this bin
|
||||
for (x = xBinStart; x < xBinEnd; x += 1) {
|
||||
if( x >= width ){ continue; }
|
||||
for (y = yBinStart; y < yBinEnd; y += 1) {
|
||||
if( y >= height ){ continue; }
|
||||
i = (width * y + x) * 4;
|
||||
imageData[i + 0] = red;
|
||||
imageData[i + 1] = green;
|
||||
imageData[i + 2] = blue;
|
||||
imageData[i + 3] = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'pixelSize', 8, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
/**
|
||||
* get/set pixel size
|
||||
* @name pixelSize
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} pixelSize
|
||||
* @returns {Integer}
|
||||
*/
|
||||
/**
|
||||
* get/set pixel size
|
||||
* @name pixelSize
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} pixelSize
|
||||
* @returns {Integer}
|
||||
*/
|
||||
})();
|
||||
@@ -1,36 +1,36 @@
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* Posterize Filter. Adjusts the channels so that there are no more
|
||||
* than n different values for that channel. This is also applied
|
||||
* to the alpha channel.
|
||||
* @function
|
||||
* @author ippo615
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
*/
|
||||
/**
|
||||
* Posterize Filter. Adjusts the channels so that there are no more
|
||||
* than n different values for that channel. This is also applied
|
||||
* to the alpha channel.
|
||||
* @function
|
||||
* @author ippo615
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
*/
|
||||
|
||||
Kinetic.Filters.Posterize = function (imageData) {
|
||||
// level must be between 1 and 255
|
||||
var levels = Math.round(this.levels() * 254) + 1,
|
||||
data = imageData.data,
|
||||
len = data.length,
|
||||
scale = (255 / levels),
|
||||
i;
|
||||
Kinetic.Filters.Posterize = function (imageData) {
|
||||
// level must be between 1 and 255
|
||||
var levels = Math.round(this.levels() * 254) + 1,
|
||||
data = imageData.data,
|
||||
len = data.length,
|
||||
scale = (255 / levels),
|
||||
i;
|
||||
|
||||
for (i = 0; i < len; i += 1) {
|
||||
data[i] = Math.floor(data[i] / scale) * scale;
|
||||
}
|
||||
};
|
||||
for (i = 0; i < len; i += 1) {
|
||||
data[i] = Math.floor(data[i] / scale) * scale;
|
||||
}
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'levels', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'levels', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
/**
|
||||
* get/set levels. Must be a number between 0 and 1
|
||||
* @name levels
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} level between 0 and 1
|
||||
* @returns {Number}
|
||||
*/
|
||||
/**
|
||||
* get/set levels. Must be a number between 0 and 1
|
||||
* @name levels
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} level between 0 and 1
|
||||
* @returns {Number}
|
||||
*/
|
||||
})();
|
||||
@@ -1,77 +1,77 @@
|
||||
(function () {
|
||||
/**
|
||||
* RGB Filter
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
Kinetic.Filters.RGB = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nPixels = data.length,
|
||||
red = this.red(),
|
||||
green = this.green(),
|
||||
blue = this.blue(),
|
||||
i, brightness;
|
||||
/**
|
||||
* RGB Filter
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
Kinetic.Filters.RGB = function (imageData) {
|
||||
var data = imageData.data,
|
||||
nPixels = data.length,
|
||||
red = this.red(),
|
||||
green = this.green(),
|
||||
blue = this.blue(),
|
||||
i, brightness;
|
||||
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
brightness = (0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2])/255;
|
||||
data[i ] = brightness*red; // r
|
||||
data[i + 1] = brightness*green; // g
|
||||
data[i + 2] = brightness*blue; // b
|
||||
data[i + 3] = data[i + 3]; // alpha
|
||||
}
|
||||
};
|
||||
for (i = 0; i < nPixels; i += 4) {
|
||||
brightness = (0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2])/255;
|
||||
data[i ] = brightness*red; // r
|
||||
data[i + 1] = brightness*green; // g
|
||||
data[i + 2] = brightness*blue; // b
|
||||
data[i + 3] = data[i + 3]; // alpha
|
||||
}
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'red', 0, function(val) {
|
||||
this._filterUpToDate = false;
|
||||
if (val > 255) {
|
||||
return 255;
|
||||
}
|
||||
else if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return Math.round(val);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* get/set filter red value
|
||||
* @name red
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} red value between 0 and 255
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'red', 0, function(val) {
|
||||
this._filterUpToDate = false;
|
||||
if (val > 255) {
|
||||
return 255;
|
||||
}
|
||||
else if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return Math.round(val);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* get/set filter red value
|
||||
* @name red
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} red value between 0 and 255
|
||||
* @returns {Integer}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'green', 0, function(val) {
|
||||
this._filterUpToDate = false;
|
||||
if (val > 255) {
|
||||
return 255;
|
||||
}
|
||||
else if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return Math.round(val);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* get/set filter green value
|
||||
* @name green
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} green value between 0 and 255
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'green', 0, function(val) {
|
||||
this._filterUpToDate = false;
|
||||
if (val > 255) {
|
||||
return 255;
|
||||
}
|
||||
else if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return Math.round(val);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* get/set filter green value
|
||||
* @name green
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} green value between 0 and 255
|
||||
* @returns {Integer}
|
||||
*/
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'blue', 0, Kinetic.Validators.RGBComponent, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set filter blue value
|
||||
* @name blue
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} blue value between 0 and 255
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'blue', 0, Kinetic.Validators.RGBComponent, Kinetic.Factory.afterSetFilter);
|
||||
/**
|
||||
* get/set filter blue value
|
||||
* @name blue
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Integer} blue value between 0 and 255
|
||||
* @returns {Integer}
|
||||
*/
|
||||
})();
|
||||
|
||||
@@ -1,40 +1,45 @@
|
||||
(function () {
|
||||
/**
|
||||
* Solarize Filter
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* Pixastic Lib - Solarize filter - v0.1.0
|
||||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
||||
* License: [http://www.pixastic.com/lib/license.txt]
|
||||
*/
|
||||
Kinetic.Filters.Solarize = function (imageData) {
|
||||
var data = imageData.data,
|
||||
w = imageData.width,
|
||||
h = imageData.height,
|
||||
w4 = w*4,
|
||||
y = h;
|
||||
/**
|
||||
* Solarize Filter
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* Pixastic Lib - Solarize filter - v0.1.0
|
||||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
||||
* License: [http://www.pixastic.com/lib/license.txt]
|
||||
*/
|
||||
Kinetic.Filters.Solarize = function (imageData) {
|
||||
var data = imageData.data,
|
||||
w = imageData.width,
|
||||
h = imageData.height,
|
||||
w4 = w*4,
|
||||
y = h;
|
||||
|
||||
do {
|
||||
var offsetY = (y-1)*w4;
|
||||
var x = w;
|
||||
do {
|
||||
var offset = offsetY + (x-1)*4;
|
||||
var r = data[offset];
|
||||
var g = data[offset+1];
|
||||
var b = data[offset+2];
|
||||
var offsetY = (y-1)*w4;
|
||||
var x = w;
|
||||
do {
|
||||
var offset = offsetY + (x-1)*4;
|
||||
var r = data[offset];
|
||||
var g = data[offset+1];
|
||||
var b = data[offset+2];
|
||||
|
||||
if (r > 127) r = 255 - r;
|
||||
if (g > 127) g = 255 - g;
|
||||
if (b > 127) b = 255 - b;
|
||||
if (r > 127) {
|
||||
r = 255 - r;
|
||||
}
|
||||
if (g > 127) {
|
||||
g = 255 - g;
|
||||
}
|
||||
if (b > 127) {
|
||||
b = 255 - b;
|
||||
}
|
||||
|
||||
data[offset] = r;
|
||||
data[offset+1] = g;
|
||||
data[offset+2] = b;
|
||||
|
||||
} while (--x);
|
||||
} while (--y);
|
||||
};
|
||||
data[offset] = r;
|
||||
data[offset+1] = g;
|
||||
data[offset+2] = b;
|
||||
} while (--x);
|
||||
} while (--y);
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* Threshold Filter. Pushes any value above the mid point to
|
||||
* the max and any value below the mid point to the min.
|
||||
* This affects the alpha channel.
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
/**
|
||||
* Threshold Filter. Pushes any value above the mid point to
|
||||
* the max and any value below the mid point to the min.
|
||||
* This affects the alpha channel.
|
||||
* @function
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
* @author ippo615
|
||||
*/
|
||||
|
||||
Kinetic.Filters.Threshold = function (imageData) {
|
||||
var level = this.threshold() * 255,
|
||||
data = imageData.data,
|
||||
len = data.length,
|
||||
i;
|
||||
Kinetic.Filters.Threshold = function (imageData) {
|
||||
var level = this.threshold() * 255,
|
||||
data = imageData.data,
|
||||
len = data.length,
|
||||
i;
|
||||
|
||||
for (i = 0; i < len; i += 1) {
|
||||
data[i] = data[i] < level ? 0 : 255;
|
||||
}
|
||||
};
|
||||
for (i = 0; i < len; i += 1) {
|
||||
data[i] = data[i] < level ? 0 : 255;
|
||||
}
|
||||
};
|
||||
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'threshold', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'threshold', 0.5, null, Kinetic.Factory.afterSetFilter);
|
||||
|
||||
/**
|
||||
* get/set threshold. Must be a value between 0 and 1
|
||||
* @name threshold
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} threshold
|
||||
* @returns {Number}
|
||||
*/
|
||||
/**
|
||||
* get/set threshold. Must be a value between 0 and 1
|
||||
* @name threshold
|
||||
* @method
|
||||
* @memberof Kinetic.Node.prototype
|
||||
* @param {Number} threshold
|
||||
* @returns {Number}
|
||||
*/
|
||||
})();
|
||||
Reference in New Issue
Block a user