Merge pull request #524 from ippo615/master

jsHint Cleanup and New Filters
This commit is contained in:
Eric Rowell
2013-07-19 11:29:47 -07:00
9 changed files with 860 additions and 30 deletions

View File

@@ -39,7 +39,9 @@ module.exports = function(grunt) {
'src/filters/Brighten.js', 'src/filters/Brighten.js',
'src/filters/Invert.js', 'src/filters/Invert.js',
'src/filters/Blur.js', 'src/filters/Blur.js',
'src/filters/Mask.js' 'src/filters/Mask.js',
'src/filters/Colors.js',
'src/filters/Convolution.js'
]; ];
var unitTestFiles = [ var unitTestFiles = [
@@ -163,4 +165,4 @@ module.exports = function(grunt) {
grunt.registerTask('full', ['clean', 'concat:source', 'replace:dev', 'uglify', 'replace:prod']); grunt.registerTask('full', ['clean', 'concat:source', 'replace:dev', 'uglify', 'replace:prod']);
grunt.registerTask('test', ['concat:test']); grunt.registerTask('test', ['concat:test']);
grunt.registerTask('hint', ['clean', 'concat:source', 'replace:dev', 'jshint']); grunt.registerTask('hint', ['clean', 'concat:source', 'replace:dev', 'jshint']);
}; };

View File

@@ -30,7 +30,7 @@
child; child;
while(children.length > 0) { while(children.length > 0) {
var child = children[0]; child = children[0];
if (child.hasChildren()) { if (child.hasChildren()) {
child.removeChildren(); child.removeChildren();
} }

View File

@@ -105,6 +105,7 @@
radiusPlus1 = radius + 1, radiusPlus1 = radius + 1,
sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2, sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2,
stackStart = new BlurStack(), stackStart = new BlurStack(),
stackEnd = null,
stack = stackStart, stack = stackStart,
stackIn = null, stackIn = null,
stackOut = null, stackOut = null,
@@ -113,7 +114,7 @@
for ( i = 1; i < div; i++ ) { for ( i = 1; i < div; i++ ) {
stack = stack.next = new BlurStack(); stack = stack.next = new BlurStack();
if ( i == radiusPlus1 ) var stackEnd = stack; if ( i == radiusPlus1 ) stackEnd = stack;
} }
stack.next = stackStart; stack.next = stackStart;
@@ -167,7 +168,7 @@
for ( x = 0; x < width; x++ ) for ( x = 0; x < width; x++ )
{ {
pixels[yi+3] = pa = (a_sum * mul_sum) >> shg_sum; pixels[yi+3] = pa = (a_sum * mul_sum) >> shg_sum;
if ( pa != 0 ) if ( pa !== 0 )
{ {
pa = 255 / pa; pa = 255 / pa;
pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa; pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa;

148
src/filters/Colors.js Normal file
View File

@@ -0,0 +1,148 @@
(function() {
var rgb_to_hsl = function(r,g,b){
// Input colors are in 0-255, calculations are between 0-1
r /= 255; g /= 255; b /= 255;
// http://en.wikipedia.org/wiki/HSL_and_HSV
// Convert to HSL
var max = Math.max(r,g,b),
min = Math.min(r,g,b),
chroma = max - min,
luminance = chroma / 2,
saturation = chroma / (1 - Math.abs(2*luminance-1)),
hue = 0;
if( max == r ){ hue = ((g-b)/chroma) % 6; }else
if( max == g ){ hue = (b-r)/chroma + 2; }else
if( max == b ){ hue = (r-g)/chroma + 4; }
return [(hue*60+360) % 360, saturation, luminance];
};
var pixelShiftHue = function(r,g,b,deg){
// Input colors are in 0-255, calculations are between 0-1
r /= 255; g /= 255; b /= 255;
// http://en.wikipedia.org/wiki/HSL_and_HSV
// Convert to HSL
var max = Math.max(r,g,b),
min = Math.min(r,g,b),
chroma = max - min,
luminance = chroma / 2,
saturation = chroma / (1 - Math.abs(2*luminance-1)),
hue = 0;
if( max == r ){ hue = ((g-b)/chroma) % 6; }else
if( max == g ){ hue = (b-r)/chroma + 2; }else
if( max == b ){ hue = (r-g)/chroma + 4; }
hue *= 60;
hue %= 360;
// Shift hue
hue += deg;
hue %= 360;
//hue /= 360;
// hsl to rgb:
hue /= 60;
var rR = 0, rG = 0, rB = 0,
//chroma = saturation*(1 - Math.abs(2*luminance - 1)),
tmp = chroma * (1-Math.abs(hue % 2 - 1)),
m = luminance - chroma/2;
if( 0 <= hue && hue < 1 ){ rR = chroma; rG = tmp; }else
if( 1 <= hue && hue < 2 ){ rG = chroma; rR = tmp; }else
if( 2 <= hue && hue < 3 ){ rG = chroma; rB = tmp; }else
if( 3 <= hue && hue < 4 ){ rB = chroma; rG = tmp; }else
if( 4 <= hue && hue < 5 ){ rB = chroma; rR = tmp; }else
if( 5 <= hue && hue < 6 ){ rR = chroma; rB = tmp; }
rR += m; rG += m; rB += m;
rR = (255*rR);
rG = (255*rG);
rB = (255*rB);
return [rR,rG,rB];
};
var shift_hue = function(imageData,deg){
var data = imageData.data,
pixel;
for(var i = 0; i < data.length; i += 4) {
pixel = pixelShiftHue(data[i+0],data[i+1],data[i+2],deg);
data[i+0] = pixel[0];
data[i+1] = pixel[1];
data[i+2] = pixel[2];
}
};
/**
* shift hue
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.ShiftHue = function(imageData) {
shift_hue(imageData,this.getFilterHueShiftDeg());
};
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterHueShiftDeg', 0);
/**
* get hue shift amount. The shift amount is a number between 0 and 360.
* @name getFilterBrightness
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* set hue shift amount
* @name setFilterBrightness
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* colorizes the image so that it is just varying shades of the specified color
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.Colorize = function(imageData) {
var data = imageData.data;
// First we'll colorize it red, then shift by the hue specified
var color = this.getFilterColorizeColor(),
hsl = rgb_to_hsl(color[0],color[1],color[2]),
hue = hsl[0];
// Color it red
for(var i = 0; i < data.length; i += 4) {
data[i + 1] = 0;
data[i + 2] = 0;
}
// Shift by the hue
shift_hue(imageData,hue);
};
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterColorizeColor', [255,0,0] );
/**
* Gets the colorizing color.
* @name getFilterColorizeColor
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* Gets the colorizing color. Should be an array [r,g,b] ie [255,0,128].
* note that white [255,255,255] black [0,0,0] and greys [r,r,r] get treated as red.
* @name setFilterColorizeColor
* @method
* @memberof Kinetic.Image.prototype
*/
})();

393
src/filters/Convolution.js Normal file
View File

@@ -0,0 +1,393 @@
(function() {
var convolve_internal = function(imageData,matrix){
// Input data
var pixels = imageData.data,
imageSizeX = imageData.width,
imageSizeY = imageData.height,
nPixels = imageSizeX*imageSizeY,
pixel;
// An array for storing the result
var result = [];
result.length = imageSizeX*imageSizeY*4;
// Determine the size and demsionality of the matrix
// Note: it should be square and odd (3,5,7,9 etc...)
var is2D = (matrix[0].length > 0) || 0,
matrixSizeX = matrix.length,
matrixSizeY = matrix.length;
// Make sure we don't try to access pixels outside the image
var xMax = Math.floor(imageSizeX - matrixSizeX/2),
xMin = Math.floor(matrixSizeX/2),
yMax = Math.floor(imageSizeY - matrixSizeY/2),
yMin = Math.floor(matrixSizeY/2);
// Accumlators and positions for iterating
var r,g,b,a, x, y, pos, i,j;
// Handle the 2D matrix
if( is2D ){
for( y=yMin; y<yMax; y+=1){
for( x=xMin; x<xMax; x+=1){
// Perform the convolution
r = 0; g = 0; b = 0; a = 0;
for( i=0; i<matrixSizeX; i+=1){
for( j=0; j<matrixSizeY; j+=1){
pos = ((y+j)*imageSizeX+x+i)*4;
r += matrix[j][i]*pixels[pos+0];
g += matrix[j][i]*pixels[pos+1];
b += matrix[j][i]*pixels[pos+2];
//a += matrix[j][i]*pixels[pos+3];
}
}
// Store the result
pos = (y*imageSizeX+x)*4;
result[pos+0] = r;
result[pos+1] = g;
result[pos+2] = b;
//result[pos+3] = a;
}
}
}
// Handle the 1D matrix
else{
// Horizontal pass (ie convolving every row of the image)
for( y=0; y<imageSizeY; y+=1){
for( x=xMin; x<xMax; x+=1){
pos = (y*imageSizeX+x)*4;
// Perform the convolution
r = 0; g = 0; b = 0; a = 0;
for( j=0; j<matrixSizeX; j+=1){
pos += 4;
r += matrix[j]*pixels[pos+0];
g += matrix[j]*pixels[pos+1];
b += matrix[j]*pixels[pos+2];
//a += matrix[j]*pixels[pos+3];
}
// Multiply by 1/2 because the other 1/2 comes from the vertical pass
pos = (y*imageSizeX+x)*4;
result[pos+0] = r*0.5;
result[pos+1] = g*0.5;
result[pos+2] = b*0.5;
//result[pos+3] = a*0.5;
}
}
// Vertical pass (ie convolving every column of the image)
for( x=0; x<imageSizeX; x+=1){
for( y=yMin; y<yMax; y+=1){
pos = (y*imageSizeX+x)*4;
// Perform the convolution
r = 0; g = 0; b = 0; a = 0;
for( j=0; j<matrixSizeX; j+=1){
pos += 4*imageSizeX;
r += matrix[j]*pixels[pos+0];
g += matrix[j]*pixels[pos+1];
b += matrix[j]*pixels[pos+2];
//a += matrix[j]*pixels[pos+3];
}
// Multiply by 1/2 and add to horizontal pass results
pos = (y*imageSizeX+x)*4;
result[pos+0] += r*0.5;
result[pos+1] += g*0.5;
result[pos+2] += b*0.5;
//result[pos+3] += a*0.5;
}
}
}
// copy the result to the original canvas
var lastPos = nPixels*4;
for( pos=0; pos<lastPos; pos+=4 ){
pixels[pos+0] = result[pos+0];
pixels[pos+1] = result[pos+1];
pixels[pos+2] = result[pos+2];
//pixels[pos+3] = result[pos+3];
}
};
// Definition of a gaussian function
var gaussian = function(x,mean,sigma){
var dx = x - mean;
return Math.pow(Math.E, -dx*dx / (2*sigma*sigma));
};
var make_blur_kernel = function( size, scale ){
// make sure size is odd:
if( size % 2 === 0 ){ size += 1; }
// Generate the kernel, we can just multiply 2 single dimensional
// gaussians to get a 2D guassian
var kernel = [], i,j, row;
for( i=0; i<size; i+=1 ){
row = [];
for( j=0; j<size; j+=1 ){
row.push( scale * gaussian(i,size/2,1) * gaussian(j,size/2,1) );
}
kernel.push(row);
}
return kernel;
};
var make_soft_blur_kernel = function( size, blur_percent ){
// A soft blur is achieve by blurring the image then
// merging the blured and unblurred image (ie 60/40).
// Instead of that we've scaling the blur kernel (ie 60)
// and adding the identity scaled (ie 40) to the kernel
var kernel = make_blur_kernel( size, blur_percent / 100 ),
mid = Math.floor(size/2);
kernel[mid][mid] += 1 - (blur_percent/100);
return kernel;
};
var make_unsharp_kernel = function( size, unsharp_percent ){
// An 'unsharp mask' is made by blurring the inverted image
// and combining it with the original (like a soft blur but
// with the blur negated). We can achieve this by negating
// blur kernel, and adding twice the identity to that kernel.
var kernel = make_blur_kernel( size, -blur_percent / 100 ),
mid = Math.floor(size/2);
kernel[mid][mid] += 2;
return kernel;
};
/**
* general convolution
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.Convolve = function(imageData) {
convolve_internal(imageData,this.getFilterConvolutionMatrix());
};
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterConvolutionMatrix', 0);
/**
* get the current convolution matrix.
* @name getFilterConvolutionMatrix
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* set the current convolution matrix, can be a single dimensional array
* or a 2D array. A 1D array will be applied horizontally then flipped
* and applied vertically. A 2D array will be applied as-is. The array
* dimensions should be odd (ie 3x3, 5x5, 7, etc...)
* @name setFilterConvolutionMatrix
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* unsharp mask
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.UnsharpMask = function(imageData) {
convolve_internal(imageData,
make_unsharp_kernel(
this.getFilterSoftBlurSize(),
this.getFilterSoftBlurAmount()
)
);
};
/**
* soft blur
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.SoftBlur = function(imageData) {
convolve_internal(imageData,
make_soft_blur_kernel(
this.getFilterSoftBlurSize(),
this.getFilterSoftBlurAmount()
)
);
};
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterSoftBlurAmount', 60);
/**
* get the soft blur amount
* @name getFilterSoftBlurAmount
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* set the soft blur amount. 0 = no blur, 100 = full blur
* @name setFilterSoftBlurAmount
* @method
* @memberof Kinetic.Image.prototype
*/
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterSoftBlurSize', 3);
/**
* get the soft blur size
* @name getFilterSoftBlurSize
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* set the soft blur size in number of pixels
* @name setFilterSoftBlurSize
* @method
* @memberof Kinetic.Image.prototype
*/
/**
* sharpening filter, makes edges more pointed
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.Sharpen = function(imageData) {
convolve_internal(imageData,[
[ 0,-2, 0],
[-2, 9,-2],
[ 0,-2, 0]
]);
};
/**
* mean removal
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.RemoveMean = function(imageData) {
convolve_internal(imageData,[
[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]
]);
};
/**
* emboss
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.Emboss = function(imageData) {
convolve_internal(imageData,[
[-2,-1, 0],
[-1, 1, 1],
[ 0, 1, 2]
]);
};
/**
* detects horizontal edges
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.DetectHorizontalEdges = function(imageData) {
convolve_internal(imageData,[
[-1,-1,-1],
[ 2, 2, 2],
[-1,-1,-1]
]);
};
/**
* detects vertical edges
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.DetectVerticalEdges = function(imageData) {
convolve_internal(imageData,[
[-1, 2,-1],
[-1, 2,-1],
[-1, 2,-1]
]);
};
/**
* detects 45* angle edges
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.DetectDiagonal45Edges = function(imageData) {
convolve_internal(imageData,[
[-1,-1, 2],
[-1, 2,-1],
[ 2,-1,-1]
]);
};
/**
* detects 135* angle edges
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.DetectDiagonal135Edges = function(imageData) {
convolve_internal(imageData,[
[ 2,-1,-1],
[-1, 2,-1],
[-1,-1, 2]
]);
};
/**
* detects edges
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.DetectEdges = function(imageData) {
convolve_internal(imageData,[
[-1,-1,-1],
[-1, 8,-1],
[-1,-1,-1]
]);
};
/**
* makes image lighter
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.Lighten = function(imageData) {
convolve_internal(imageData,[
[ 0, 0, 0],
[ 0,1.2, 0],
[ 0, 0, 0]
]);
};
/**
* makes image darker
* @function
* @memberof Kinetic.Filters
* @param {Object} imageData
*/
Kinetic.Filters.Darken = function(imageData) {
convolve_internal(imageData,[
[ 0, 0, 0],
[ 0,0.8, 0],
[ 0, 0, 0]
]);
};
})();

View File

@@ -5,11 +5,11 @@
var d = []; var d = [];
d.push(idata.data[idx++], idata.data[idx++], idata.data[idx++], idata.data[idx++]); d.push(idata.data[idx++], idata.data[idx++], idata.data[idx++], idata.data[idx++]);
return d; return d;
}; }
function rgbDistance(p1, p2) { function rgbDistance(p1, p2) {
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[2] - p2[2], 2)); return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[2] - p2[2], 2));
}; }
function rgbMean(pTab) { function rgbMean(pTab) {
var m = [0, 0, 0]; var m = [0, 0, 0];
@@ -25,7 +25,7 @@
m[2] /= pTab.length; m[2] /= pTab.length;
return m; return m;
}; }
function backgroundMask(idata, threshold) { function backgroundMask(idata, threshold) {
var rgbv_no = pixelAt(idata, 0, 0); var rgbv_no = pixelAt(idata, 0, 0);
@@ -49,13 +49,13 @@
return mask; return mask;
} }
}; }
function applyMask(idata, mask) { function applyMask(idata, mask) {
for (var i = 0; i < idata.width * idata.height; i++) { for (var i = 0; i < idata.width * idata.height; i++) {
idata.data[4 * i + 3] = mask[i]; idata.data[4 * i + 3] = mask[i];
} }
}; }
function erodeMask(mask, sw, sh) { function erodeMask(mask, sw, sh) {
@@ -89,7 +89,7 @@
} }
return maskResult; return maskResult;
}; }
function dilateMask(mask, sw, sh) { function dilateMask(mask, sw, sh) {
@@ -123,7 +123,7 @@
} }
return maskResult; return maskResult;
}; }
function smoothEdgeMask(mask, sw, sh) { function smoothEdgeMask(mask, sw, sh) {
@@ -171,7 +171,7 @@
Kinetic.Filters.Mask = function(idata) { Kinetic.Filters.Mask = function(idata) {
// Detect pixels close to the background color // Detect pixels close to the background color
var threshold = this.getFilterThreshold(), var threshold = this.getFilterThreshold(),
mask = backgroundMask(idata, threshold); mask = backgroundMask(idata, threshold);
if (mask) { if (mask) {
// Erode // Erode
mask = erodeMask(mask, idata.width, idata.height); mask = erodeMask(mask, idata.width, idata.height);

View File

@@ -90,11 +90,13 @@
_addListeners: function(context) { _addListeners: function(context) {
var that = this, var that = this,
n; n;
var func = function(){
that._sync();
};
// update text data for certain attr changes // update text data for certain attr changes
for(n = 0; n < attrChangeListLen; n++) { for(n = 0; n < attrChangeListLen; n++) {
context.on(ATTR_CHANGE_LIST[n] + CHANGE_KINETIC, function() { context.on(ATTR_CHANGE_LIST[n] + CHANGE_KINETIC, func);
that._sync();
});
} }
}, },
getWidth: function() { getWidth: function() {
@@ -292,4 +294,4 @@
* @method * @method
* @memberof Kinetic.Tag.prototype * @memberof Kinetic.Tag.prototype
*/ */
})(); })();

View File

@@ -235,7 +235,7 @@
// init context point // init context point
var cpx = 0; var cpx = 0;
var cpy = 0; var cpy = 0;
for(var n = 1; n < arr.length; n++) { for( n = 1; n < arr.length; n++) {
var str = arr[n]; var str = arr[n];
var c = str.charAt(0); var c = str.charAt(0);
str = str.slice(1); str = str.slice(1);
@@ -259,6 +259,10 @@
var cmd = null; var cmd = null;
var points = []; var points = [];
var startX = cpx, startY = cpy; var startX = cpx, startY = cpy;
// Move var from within the switch to up here (jshint)
var prevCmd, ctlPtx, ctlPty; // Ss, Tt
var rx, ry, psi, fa, fs, x1, y1; // Aa
// convert l, H, h, V, and v to L // convert l, H, h, V, and v to L
switch (c) { switch (c) {
@@ -328,8 +332,8 @@
points.push(cpx, cpy); points.push(cpx, cpy);
break; break;
case 'S': case 'S':
var ctlPtx = cpx, ctlPty = cpy; ctlPtx = cpx, ctlPty = cpy;
var prevCmd = ca[ca.length - 1]; prevCmd = ca[ca.length - 1];
if(prevCmd.command === 'C') { if(prevCmd.command === 'C') {
ctlPtx = cpx + (cpx - prevCmd.points[2]); ctlPtx = cpx + (cpx - prevCmd.points[2]);
ctlPty = cpy + (cpy - prevCmd.points[3]); ctlPty = cpy + (cpy - prevCmd.points[3]);
@@ -341,8 +345,8 @@
points.push(cpx, cpy); points.push(cpx, cpy);
break; break;
case 's': case 's':
var ctlPtx = cpx, ctlPty = cpy; ctlPtx = cpx, ctlPty = cpy;
var prevCmd = ca[ca.length - 1]; prevCmd = ca[ca.length - 1];
if(prevCmd.command === 'C') { if(prevCmd.command === 'C') {
ctlPtx = cpx + (cpx - prevCmd.points[2]); ctlPtx = cpx + (cpx - prevCmd.points[2]);
ctlPty = cpy + (cpy - prevCmd.points[3]); ctlPty = cpy + (cpy - prevCmd.points[3]);
@@ -367,8 +371,8 @@
points.push(cpx, cpy); points.push(cpx, cpy);
break; break;
case 'T': case 'T':
var ctlPtx = cpx, ctlPty = cpy; ctlPtx = cpx, ctlPty = cpy;
var prevCmd = ca[ca.length - 1]; prevCmd = ca[ca.length - 1];
if(prevCmd.command === 'Q') { if(prevCmd.command === 'Q') {
ctlPtx = cpx + (cpx - prevCmd.points[0]); ctlPtx = cpx + (cpx - prevCmd.points[0]);
ctlPty = cpy + (cpy - prevCmd.points[1]); ctlPty = cpy + (cpy - prevCmd.points[1]);
@@ -379,8 +383,8 @@
points.push(ctlPtx, ctlPty, cpx, cpy); points.push(ctlPtx, ctlPty, cpx, cpy);
break; break;
case 't': case 't':
var ctlPtx = cpx, ctlPty = cpy; ctlPtx = cpx, ctlPty = cpy;
var prevCmd = ca[ca.length - 1]; prevCmd = ca[ca.length - 1];
if(prevCmd.command === 'Q') { if(prevCmd.command === 'Q') {
ctlPtx = cpx + (cpx - prevCmd.points[0]); ctlPtx = cpx + (cpx - prevCmd.points[0]);
ctlPty = cpy + (cpy - prevCmd.points[1]); ctlPty = cpy + (cpy - prevCmd.points[1]);
@@ -391,14 +395,14 @@
points.push(ctlPtx, ctlPty, cpx, cpy); points.push(ctlPtx, ctlPty, cpx, cpy);
break; break;
case 'A': case 'A':
var rx = p.shift(), ry = p.shift(), psi = p.shift(), fa = p.shift(), fs = p.shift(); rx = p.shift(), ry = p.shift(), psi = p.shift(), fa = p.shift(), fs = p.shift();
var x1 = cpx, y1 = cpy; cpx = p.shift(), cpy = p.shift(); x1 = cpx, y1 = cpy; cpx = p.shift(), cpy = p.shift();
cmd = 'A'; cmd = 'A';
points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi); points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi);
break; break;
case 'a': case 'a':
var rx = p.shift(), ry = p.shift(), psi = p.shift(), fa = p.shift(), fs = p.shift(); rx = p.shift(), ry = p.shift(), psi = p.shift(), fa = p.shift(), fs = p.shift();
var x1 = cpx, y1 = cpy; cpx += p.shift(), cpy += p.shift(); x1 = cpx, y1 = cpy; cpx += p.shift(), cpy += p.shift();
cmd = 'A'; cmd = 'A';
points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi); points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi);
break; break;

View File

@@ -1432,6 +1432,286 @@ Test.Modules.IMAGE = {
}; };
imageObj.src = '../assets/darth-vader.jpg'; imageObj.src = '../assets/darth-vader.jpg';
}, },
'colorizing filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.Colorize);
darth.setFilterColorizeColor([255,0,128]);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'colorizing filter', 'problem with colorizing filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
},
'shift hue filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.ShiftHue);
darth.setFilterHueShiftDeg(90);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'shift hue filter', 'problem with hue shifting filter.');
};
imageObj.src = '../assets/lion.png';
},
'unsharp mask filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.UnsharpMask);
darth.setFilterSoftBlurAmount(90);
darth.setFilterSoftBlurSize(7);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'unsharp mask filter', 'problem with unsharp mask filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'soft blur filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.SoftBlur);
darth.setFilterSoftBlurAmount(10);
darth.setFilterSoftBlurSize(7);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'soft blur filter', 'problem with soft blur filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'sharpen filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.Sharpen);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'sharpen filter', 'problem with sharpen filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'remove mean filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.RemoveMean);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'remove mean filter', 'problem with remove mean filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'emboss filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.Emboss);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'emboss filter', 'problem with emboss filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'edge detection filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
//darth.setFilter(Kinetic.Filters.DetectHorizontalEdge);
//darth.setFilter(Kinetic.Filters.DetectVerticalEdge);
//darth.setFilter(Kinetic.Filters.DetectDiagonal45Edge);
//darth.setFilter(Kinetic.Filters.DetectDiagonal135Edge);
darth.setFilter(Kinetic.Filters.DetectEdges);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'edge detection filter', 'problem with edge detection filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'lighten filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.Lighten);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'lighten filter', 'problem with lighten filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'darken filter': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
darth = new Kinetic.Image({
x: 10,
y: 10,
image: imageObj,
draggable: true
});
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.Darken);
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
testDataUrl(dataUrl, 'darken filter', 'problem with darken filter.');
};
imageObj.src = '../assets/darth-vader.jpg';
//imageObj.src = '../assets/lion.png';
},
'filter transformed image': function(containerId) { 'filter transformed image': function(containerId) {
var imageObj = new Image(); var imageObj = new Image();
imageObj.onload = function() { imageObj.onload = function() {