mirror of
https://github.com/konvajs/konva.git
synced 2026-01-18 19:51:21 +08:00
Made convolution filters tweenable.
Unsharp mask, soft blur, sharpen, emboss, edge detect are now "tweenable"; however, I think I need to tweak the convolution matricies. At 0 there should be no effect applied which corresponds to a matrix with just a `1` in the middle (ie [...1...]). If the `filterAmount` is small then the matrix is all near 0's causing the image to 'flash black'. If I always add a 1 in the middle then the images become too bright...
This commit is contained in:
@@ -65,7 +65,7 @@
|
|||||||
}
|
}
|
||||||
// Handle the 1D matrix
|
// Handle the 1D matrix
|
||||||
else{
|
else{
|
||||||
|
// WARNING: THIS NEEDS TO BE UPDATED!!! TO HANDLE TILING
|
||||||
// Horizontal pass (ie convolving every row of the image)
|
// Horizontal pass (ie convolving every row of the image)
|
||||||
for( y=0; y<imageSizeY; y+=1){
|
for( y=0; y<imageSizeY; y+=1){
|
||||||
for( x=xMin; x<xMax; x+=1){
|
for( x=xMin; x<xMax; x+=1){
|
||||||
@@ -150,38 +150,44 @@
|
|||||||
return kernel;
|
return kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
var make_soft_blur_kernel = function( size, blur_percent ){
|
var make_soft_blur_kernel = function( size, percent ){
|
||||||
// A soft blur is achieve by blurring the image then
|
// A soft blur is achieve by blurring the image then
|
||||||
// merging the blured and unblurred image (ie 60/40).
|
// merging the blured and unblurred image (ie 60/40).
|
||||||
// Instead of that we've scaling the blur kernel (ie 60)
|
// Instead of that we've scaling the blur kernel (ie 60)
|
||||||
// and adding the identity scaled (ie 40) to the kernel
|
// and adding the identity scaled (ie 40) to the kernel
|
||||||
var kernel = make_blur_kernel( size, blur_percent / 100 ),
|
var kernel = make_blur_kernel( size, percent / 100 ),
|
||||||
mid = Math.floor(size/2);
|
mid = Math.floor(size/2);
|
||||||
kernel[mid][mid] += 1 - (blur_percent/100);
|
kernel[mid][mid] += 1 - (percent/100);
|
||||||
return kernel;
|
return kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
var make_unsharp_kernel = function( size, unsharp_percent ){
|
var make_unsharp_kernel = function( size, percent ){
|
||||||
// An 'unsharp mask' is made by blurring the inverted image
|
// An 'unsharp mask' is made by blurring the inverted image
|
||||||
// and combining it with the original (like a soft blur but
|
// and combining it with the original (like a soft blur but
|
||||||
// with the blur negated). We can achieve this by negating
|
// with the blur negated). We can achieve this by negating
|
||||||
// blur kernel, and adding twice the identity to that kernel.
|
// blur kernel, and adding twice the identity to that kernel.
|
||||||
var kernel = make_blur_kernel( size, -blur_percent / 100 ),
|
var kernel = make_blur_kernel( size, -percent / 100 ),
|
||||||
mid = Math.floor(size/2);
|
mid = Math.floor(size/2);
|
||||||
kernel[mid][mid] += 2;
|
kernel[mid][mid] += 1 + (percent/100);
|
||||||
return kernel;
|
return kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterAmount', 50);
|
||||||
/**
|
/**
|
||||||
* general convolution
|
* get the current filter amount
|
||||||
* @function
|
* @name getFilterAmount
|
||||||
* @memberof Kinetic.Filters
|
* @method
|
||||||
* @param {Object} imageData
|
* @memberof Kinetic.Image.prototype
|
||||||
* @author ippo615
|
|
||||||
*/
|
*/
|
||||||
Kinetic.Filters.Convolve = function(imageData) {
|
|
||||||
convolve_internal(imageData,this.getFilterConvolutionMatrix());
|
/**
|
||||||
};
|
* set the current filter amount 0 = no filter, 100 = max filter
|
||||||
|
* @name setFilterAmount
|
||||||
|
* @method
|
||||||
|
* @memberof Kinetic.Image.prototype
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterConvolutionMatrix', 0);
|
Kinetic.Node.addFilterGetterSetter(Kinetic.Image, 'filterConvolutionMatrix', 0);
|
||||||
/**
|
/**
|
||||||
@@ -210,8 +216,8 @@
|
|||||||
Kinetic.Filters.UnsharpMask = function(imageData) {
|
Kinetic.Filters.UnsharpMask = function(imageData) {
|
||||||
convolve_internal(imageData,
|
convolve_internal(imageData,
|
||||||
make_unsharp_kernel(
|
make_unsharp_kernel(
|
||||||
this.getFilterSoftBlurSize(),
|
5,
|
||||||
this.getFilterSoftBlurAmount()
|
this.getFilterAmount()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -225,41 +231,12 @@
|
|||||||
Kinetic.Filters.SoftBlur = function(imageData) {
|
Kinetic.Filters.SoftBlur = function(imageData) {
|
||||||
convolve_internal(imageData,
|
convolve_internal(imageData,
|
||||||
make_soft_blur_kernel(
|
make_soft_blur_kernel(
|
||||||
this.getFilterSoftBlurSize(),
|
5,
|
||||||
this.getFilterSoftBlurAmount()
|
this.getFilterAmount()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
* sharpening filter, makes edges more pointed
|
||||||
@@ -268,24 +245,12 @@
|
|||||||
* @param {Object} imageData
|
* @param {Object} imageData
|
||||||
*/
|
*/
|
||||||
Kinetic.Filters.Sharpen = function(imageData) {
|
Kinetic.Filters.Sharpen = function(imageData) {
|
||||||
|
var s = this.getFilterAmount()/100;
|
||||||
|
if( s === 0 ){ return; }
|
||||||
convolve_internal(imageData,[
|
convolve_internal(imageData,[
|
||||||
[ 0,-2, 0],
|
[ 0, -1*s, 0],
|
||||||
[-2, 9,-2],
|
[-1*s, 4*s,-1*s],
|
||||||
[ 0,-2, 0]
|
[ 0, -1*s, 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]
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -296,10 +261,12 @@
|
|||||||
* @param {Object} imageData
|
* @param {Object} imageData
|
||||||
*/
|
*/
|
||||||
Kinetic.Filters.Emboss = function(imageData) {
|
Kinetic.Filters.Emboss = function(imageData) {
|
||||||
|
var s = this.getFilterAmount()/100;
|
||||||
|
if( s === 0 ){ return; }
|
||||||
convolve_internal(imageData,[
|
convolve_internal(imageData,[
|
||||||
[-2,-1, 0],
|
[-1*s,-.5*s, 0],
|
||||||
[-1, 1, 1],
|
[-.5*s,1+.5*s, .5*s],
|
||||||
[ 0, 1, 2]
|
[ 0, .5*s, 1*s]
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -366,10 +333,12 @@
|
|||||||
* @param {Object} imageData
|
* @param {Object} imageData
|
||||||
*/
|
*/
|
||||||
Kinetic.Filters.DetectEdges = function(imageData) {
|
Kinetic.Filters.DetectEdges = function(imageData) {
|
||||||
|
var s = this.getFilterAmount()/100;
|
||||||
|
if( s === 0 ){ return; }
|
||||||
convolve_internal(imageData,[
|
convolve_internal(imageData,[
|
||||||
[-1,-1,-1],
|
[-1*s,-1*s,-1*s],
|
||||||
[-1, 8,-1],
|
[-1*s, 8*s,-1*s],
|
||||||
[-1,-1,-1]
|
[-1*s,-1*s,-1*s]
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1523,9 +1523,24 @@ Test.Modules.IMAGE = {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
darth.setFilter(Kinetic.Filters.UnsharpMask);
|
darth.setFilter(Kinetic.Filters.UnsharpMask);
|
||||||
darth.setFilterSoftBlurAmount(90);
|
darth.setFilterAmount(100);
|
||||||
darth.setFilterSoftBlurSize(7);
|
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var tween = new Kinetic.Tween({
|
||||||
|
node: darth,
|
||||||
|
duration: 0.6,
|
||||||
|
filterAmount: 0,
|
||||||
|
easing: Kinetic.Easings.EaseInOut
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseover', function() {
|
||||||
|
tween.play();
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseout', function() {
|
||||||
|
tween.reverse();
|
||||||
|
});
|
||||||
|
|
||||||
var dataUrl = layer.toDataURL();
|
var dataUrl = layer.toDataURL();
|
||||||
//console.log(dataUrl);
|
//console.log(dataUrl);
|
||||||
testDataUrl(dataUrl, 'unsharp mask filter', 'problem with unsharp mask filter.');
|
testDataUrl(dataUrl, 'unsharp mask filter', 'problem with unsharp mask filter.');
|
||||||
@@ -1552,9 +1567,24 @@ Test.Modules.IMAGE = {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
darth.setFilter(Kinetic.Filters.SoftBlur);
|
darth.setFilter(Kinetic.Filters.SoftBlur);
|
||||||
darth.setFilterSoftBlurAmount(10);
|
darth.setFilterAmount(100);
|
||||||
darth.setFilterSoftBlurSize(7);
|
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var tween = new Kinetic.Tween({
|
||||||
|
node: darth,
|
||||||
|
duration: 0.6,
|
||||||
|
filterAmount: 0,
|
||||||
|
easing: Kinetic.Easings.EaseInOut
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseover', function() {
|
||||||
|
tween.play();
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseout', function() {
|
||||||
|
tween.reverse();
|
||||||
|
});
|
||||||
|
|
||||||
var dataUrl = layer.toDataURL();
|
var dataUrl = layer.toDataURL();
|
||||||
//console.log(dataUrl);
|
//console.log(dataUrl);
|
||||||
testDataUrl(dataUrl, 'soft blur filter', 'problem with soft blur filter.');
|
testDataUrl(dataUrl, 'soft blur filter', 'problem with soft blur filter.');
|
||||||
@@ -1581,7 +1611,24 @@ Test.Modules.IMAGE = {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
darth.setFilter(Kinetic.Filters.Sharpen);
|
darth.setFilter(Kinetic.Filters.Sharpen);
|
||||||
|
darth.setFilterAmount(100);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var tween = new Kinetic.Tween({
|
||||||
|
node: darth,
|
||||||
|
duration: 0.6,
|
||||||
|
filterAmount: 0,
|
||||||
|
easing: Kinetic.Easings.EaseInOut
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseover', function() {
|
||||||
|
tween.play();
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseout', function() {
|
||||||
|
tween.reverse();
|
||||||
|
});
|
||||||
|
|
||||||
var dataUrl = layer.toDataURL();
|
var dataUrl = layer.toDataURL();
|
||||||
//console.log(dataUrl);
|
//console.log(dataUrl);
|
||||||
testDataUrl(dataUrl, 'sharpen filter', 'problem with sharpen filter.');
|
testDataUrl(dataUrl, 'sharpen filter', 'problem with sharpen filter.');
|
||||||
@@ -1589,33 +1636,6 @@ Test.Modules.IMAGE = {
|
|||||||
imageObj.src = '../assets/darth-vader.jpg';
|
imageObj.src = '../assets/darth-vader.jpg';
|
||||||
//imageObj.src = '../assets/lion.png';
|
//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) {
|
'emboss filter': function(containerId) {
|
||||||
var imageObj = new Image();
|
var imageObj = new Image();
|
||||||
imageObj.onload = function() {
|
imageObj.onload = function() {
|
||||||
@@ -1635,7 +1655,24 @@ Test.Modules.IMAGE = {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
darth.setFilter(Kinetic.Filters.Emboss);
|
darth.setFilter(Kinetic.Filters.Emboss);
|
||||||
|
darth.setFilterAmount(50);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var tween = new Kinetic.Tween({
|
||||||
|
node: darth,
|
||||||
|
duration: 0.6,
|
||||||
|
filterAmount: 0,
|
||||||
|
easing: Kinetic.Easings.EaseInOut
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseover', function() {
|
||||||
|
tween.play();
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseout', function() {
|
||||||
|
tween.reverse();
|
||||||
|
});
|
||||||
|
|
||||||
var dataUrl = layer.toDataURL();
|
var dataUrl = layer.toDataURL();
|
||||||
//console.log(dataUrl);
|
//console.log(dataUrl);
|
||||||
testDataUrl(dataUrl, 'emboss filter', 'problem with emboss filter.');
|
testDataUrl(dataUrl, 'emboss filter', 'problem with emboss filter.');
|
||||||
@@ -1666,7 +1703,24 @@ Test.Modules.IMAGE = {
|
|||||||
//darth.setFilter(Kinetic.Filters.DetectDiagonal45Edge);
|
//darth.setFilter(Kinetic.Filters.DetectDiagonal45Edge);
|
||||||
//darth.setFilter(Kinetic.Filters.DetectDiagonal135Edge);
|
//darth.setFilter(Kinetic.Filters.DetectDiagonal135Edge);
|
||||||
darth.setFilter(Kinetic.Filters.DetectEdges);
|
darth.setFilter(Kinetic.Filters.DetectEdges);
|
||||||
|
darth.setFilterAmount(50);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var tween = new Kinetic.Tween({
|
||||||
|
node: darth,
|
||||||
|
duration: 0.6,
|
||||||
|
filterAmount: 0,
|
||||||
|
easing: Kinetic.Easings.EaseInOut
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseover', function() {
|
||||||
|
tween.play();
|
||||||
|
});
|
||||||
|
|
||||||
|
darth.on('mouseout', function() {
|
||||||
|
tween.reverse();
|
||||||
|
});
|
||||||
|
|
||||||
var dataUrl = layer.toDataURL();
|
var dataUrl = layer.toDataURL();
|
||||||
//console.log(dataUrl);
|
//console.log(dataUrl);
|
||||||
testDataUrl(dataUrl, 'edge detection filter', 'problem with edge detection filter.');
|
testDataUrl(dataUrl, 'edge detection filter', 'problem with edge detection filter.');
|
||||||
|
|||||||
Reference in New Issue
Block a user