mirror of
https://github.com/konvajs/konva.git
synced 2026-03-03 16:58:33 +08:00
Improved Colorization filter.
- Looks better (brightness of original is preserved) - Improved speed (2-6 times faster than original) - Reduced code
This commit is contained in:
@@ -86,6 +86,18 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Kinetic.Filters.ShiftHue = function(src,dst,opt){
|
||||||
|
if( this === Kinetic.Filters ){
|
||||||
|
HSV(src, dst||src, opt );
|
||||||
|
}else{
|
||||||
|
HSV.call(this, src, dst||src, opt || {
|
||||||
|
hue: this.getFilterHueShiftDeg()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterHueShiftDeg', 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get filter hue. Returns the hue shift for the HSV filter.
|
* get filter hue. Returns the hue shift for the HSV filter.
|
||||||
* 0 is no change, 359 is the maximum shift.
|
* 0 is no change, 359 is the maximum shift.
|
||||||
@@ -134,114 +146,7 @@
|
|||||||
* @memberof Kinetic.Image.prototype
|
* @memberof Kinetic.Image.prototype
|
||||||
*/
|
*/
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
(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 Filter.
|
|
||||||
* @function
|
|
||||||
* @memberof Kinetic.Filters
|
|
||||||
* @param {Object} imageData
|
|
||||||
* @author ippo615
|
|
||||||
*/
|
|
||||||
Kinetic.Filters.ShiftHue = function(imageData) {
|
|
||||||
shift_hue(imageData, this.getFilterHueShiftDeg() % 360 );
|
|
||||||
};
|
|
||||||
|
|
||||||
Kinetic.Factory.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -252,23 +157,31 @@
|
|||||||
* @param {Object} imageData
|
* @param {Object} imageData
|
||||||
* @author ippo615
|
* @author ippo615
|
||||||
*/
|
*/
|
||||||
Kinetic.Filters.Colorize = function(imageData) {
|
var Colorize = function (src, dst, opt) {
|
||||||
var data = imageData.data;
|
var srcPixels = src.data,
|
||||||
|
dstPixels = dst.data,
|
||||||
|
nPixels = srcPixels.length,
|
||||||
|
color = opt.colorizeColor || [255,0,0],
|
||||||
|
i, brightness;
|
||||||
|
|
||||||
// First we'll colorize it red, then shift by the hue specified
|
for (i = 0; i < nPixels; i += 4) {
|
||||||
var color = this.getFilterColorizeColor(),
|
brightness = (0.34 * srcPixels[i] + 0.5 * srcPixels[i + 1] + 0.16 * srcPixels[i + 2])/255;
|
||||||
hsl = rgb_to_hsl(color[0],color[1],color[2]),
|
dstPixels[i ] = brightness*color[0]; // r
|
||||||
hue = hsl[0];
|
dstPixels[i + 1] = brightness*color[1]; // g
|
||||||
|
dstPixels[i + 2] = brightness*color[2]; // b
|
||||||
|
dstPixels[i + 3] = srcPixels[i + 3]; // alpha
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Color it red, by removing green and blue
|
Kinetic.Filters.Colorize = function(src,dst,opt){
|
||||||
for(var i = 0; i < data.length; i += 4) {
|
if( this === Kinetic.Filters ){
|
||||||
data[i + 1] = 0;
|
Colorize(src, dst||src, opt );
|
||||||
data[i + 2] = 0;
|
}else{
|
||||||
}
|
Colorize.call(this, src, dst||src, opt || {
|
||||||
|
colorizeColor: this.getFilterColorizeColor()
|
||||||
// Shift by the hue
|
});
|
||||||
shift_hue(imageData,hue);
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterColorizeColor', [255,0,0] );
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterColorizeColor', [255,0,0] );
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -64,28 +64,48 @@ suite('Color Pack', function() {
|
|||||||
// ======================================================
|
// ======================================================
|
||||||
test('colorize transparancy', function(done) {
|
test('colorize transparancy', function(done) {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
|
||||||
var imageObj = new Image();
|
var colors = [
|
||||||
imageObj.onload = function() {
|
[255,0,0],
|
||||||
|
[255,128,0],
|
||||||
|
[255,255,0],
|
||||||
|
[0,255,0],
|
||||||
|
[0,255,128],
|
||||||
|
[0,255,255],
|
||||||
|
[0,0,255],
|
||||||
|
[128,0,255],
|
||||||
|
[255,0,255],
|
||||||
|
[0,0,0],
|
||||||
|
[128,128,128],
|
||||||
|
[255,255,255]
|
||||||
|
];
|
||||||
|
var i,l = colors.length;
|
||||||
|
var nAdded = 0;
|
||||||
|
for( i=0; i<l; i+=1 ){
|
||||||
|
var imageObj = new Image();
|
||||||
|
imageObj.onload = (function(color,x){ return function() {
|
||||||
|
|
||||||
var layer = new Kinetic.Layer();
|
var darth = new Kinetic.Image({
|
||||||
darth = new Kinetic.Image({
|
x: x,
|
||||||
x: 10,
|
y: 32,
|
||||||
y: 10,
|
image: imageObj,
|
||||||
image: imageObj,
|
draggable: true
|
||||||
draggable: true
|
});
|
||||||
});
|
layer.add(darth);
|
||||||
|
|
||||||
layer.add(darth);
|
darth.setFilter(Kinetic.Filters.Colorize);
|
||||||
stage.add(layer);
|
darth.setFilterColorizeColor(color);
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.Colorize);
|
nAdded += 1;
|
||||||
darth.setFilterColorizeColor([0,128,255]);
|
if( nAdded >= l ){
|
||||||
layer.draw();
|
stage.add(layer);
|
||||||
|
layer.draw();
|
||||||
done();
|
done();
|
||||||
};
|
}
|
||||||
imageObj.src = 'assets/lion.png';
|
};})(colors[i],-64+i/l*stage.getWidth());
|
||||||
|
imageObj.src = 'assets/lion.png';
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user