Improved performance of convolution filters.

Previously, I would work with a regular array and compute/store/copy
to/from that array. It should be faster to create an imageData object,
create the convolution result in that object and finally:
`context.putImageData(result)`.
This commit is contained in:
ippo615
2013-08-04 14:34:56 -04:00
parent e631eff6b4
commit d355b1fe97

View File

@@ -1,6 +1,6 @@
(function() { (function() {
var convolve_internal = function(imageData,matrix){ var convolve_internal = function(imageData,matrix,result){
// Input data // Input data
var pixels = imageData.data, var pixels = imageData.data,
imageSizeX = imageData.width, imageSizeX = imageData.width,
@@ -9,8 +9,9 @@
pixel; pixel;
// An array for storing the result // An array for storing the result
var result = []; // (this should now be passed as the 3rd argument)
result.length = imageSizeX*imageSizeY*4; // var result = [];
// result.length = imageSizeX*imageSizeY*4;
// Determine the size and demsionality of the matrix // Determine the size and demsionality of the matrix
// Note: it should be square and odd (3,5,7,9 etc...) // Note: it should be square and odd (3,5,7,9 etc...)
@@ -57,13 +58,14 @@
} }
// copy the result to the original canvas // copy the result to the original canvas
var lastPos = nPixels*4; // Should now be handled by the CALLER using the `result` argument
for( pos=0; pos<lastPos; pos+=4 ){ //var lastPos = nPixels*4;
pixels[pos+0] = result[pos+0]; //for( pos=0; pos<lastPos; pos+=4 ){
pixels[pos+1] = result[pos+1]; // pixels[pos+0] = result[pos+0];
pixels[pos+2] = result[pos+2]; // pixels[pos+1] = result[pos+1];
//pixels[pos+3] = result[pos+3]; // pixels[pos+2] = result[pos+2];
} // //pixels[pos+3] = result[pos+3];
//}
}; };
// Definition of a gaussian function // Definition of a gaussian function
@@ -176,9 +178,14 @@
* @param {Object} imageData * @param {Object} imageData
*/ */
Kinetic.Filters.UnsharpMask = function(imageData) { Kinetic.Filters.UnsharpMask = function(imageData) {
// Create a temporary image for the result, perform the convolution
// then copy the result back
var result = this.getCanvas().getContext('2d').createImageData(imageData.width,imageData.height);
convolve_internal(imageData, convolve_internal(imageData,
make_unsharp_kernel(5,this.getFilterAmount()/100) make_unsharp_kernel(5,this.getFilterAmount()/100),
result
); );
this.getCanvas().getContext('2d').putImageData(result,0,0);
}; };
/** /**
@@ -188,9 +195,12 @@
* @param {Object} imageData * @param {Object} imageData
*/ */
Kinetic.Filters.SoftBlur = function(imageData) { Kinetic.Filters.SoftBlur = function(imageData) {
var result = this.getCanvas().getContext('2d').createImageData(imageData.width,imageData.height);
convolve_internal(imageData, convolve_internal(imageData,
make_soft_blur_kernel(5,this.getFilterAmount()/100) make_soft_blur_kernel(5,this.getFilterAmount()/100),
result
); );
this.getCanvas().getContext('2d').putImageData(result,0,0);
}; };
@@ -203,11 +213,14 @@
Kinetic.Filters.Edge = function(imageData) { Kinetic.Filters.Edge = function(imageData) {
var s = this.getFilterAmount()/100; var s = this.getFilterAmount()/100;
if( s === 0 ){ return; } if( s === 0 ){ return; }
convolve_internal(imageData,[ var matrix = [
[ 0, -1*s, 0], [ 0, -1*s, 0],
[-1*s,(1-s)+4*s,-1*s], [-1*s,(1-s)+4*s,-1*s],
[ 0, -1*s, 0] [ 0, -1*s, 0]
]); ];
var result = this.getCanvas().getContext('2d').createImageData(imageData.width,imageData.height);
convolve_internal(imageData,matrix,result);
this.getCanvas().getContext('2d').putImageData(result,0,0);
}; };
/** /**
@@ -219,11 +232,14 @@
Kinetic.Filters.Emboss = function(imageData) { Kinetic.Filters.Emboss = function(imageData) {
var s = this.getFilterAmount()/100; var s = this.getFilterAmount()/100;
if( s === 0 ){ return; } if( s === 0 ){ return; }
convolve_internal(imageData,[ var matrix = [
[-1*s,-0.5*s, 0], [-1*s,-0.5*s, 0],
[-0.5*s,1+0.5*s, 0.5*s], [-0.5*s,1+0.5*s, 0.5*s],
[ 0, 0.5*s, 1*s] [ 0, 0.5*s, 1*s]
]); ];
var result = this.getCanvas().getContext('2d').createImageData(imageData.width,imageData.height);
convolve_internal(imageData,matrix,result);
this.getCanvas().getContext('2d').putImageData(result,0,0);
}; };
})(); })();