updated Levels filter and test

This commit is contained in:
Eric Rowell 2014-01-02 22:58:36 -08:00
parent bbfbadfee2
commit a238cf5817
3 changed files with 26 additions and 171 deletions

View File

@ -4,54 +4,35 @@
* Levels 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.
* Performs w*h 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.quantizationLevels], the number of values allowed for each
* channel. Between 2 and 255. Default is 2.
* @param {Object} imageData
*/
var Levels = function (src, dst, opt) {
var nLevels = Math.round(opt.quantizationLevels || 2);
var srcPixels = src.data,
dstPixels = dst.data,
nPixels = srcPixels.length,
scale = (255 / nLevels),
i;
for (i = 0; i < nPixels; i += 1) {
dstPixels[i] = Math.floor(srcPixels[i] / scale) * scale;
Kinetic.Filters.Levels = function (imageData) {
// level must be between 1 and 255
var level = Math.round(this.level() * 254) + 1,
data = imageData.data,
len = data.length,
scale = (255 / level),
i;
for (i = 0; i < len; i += 1) {
data[i] = Math.floor(data[i] / scale) * scale;
}
};
Kinetic.Filters.Levels = function(src,dst,opt){
if( this === Kinetic.Filters ){
Levels(src, dst||src, opt );
}else{
Levels.call(this, src, dst||src, {
quantizationLevels: this.getQuantizationLevels()
});
}
};
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'quantizationLevels', 4);
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'level', 0.5);
/**
* get quantization levels. Returns the number of unique levels for each color
* channel. 2 is the minimum, 255 is the maximum. For Kinetic.Filters.Levels
* @name getQuantizationLevels
* get/set levels. Must be a number between 0 and 1
* @name level
* @method
* @memberof Kinetic.Image.prototype
* @memberof Kinetic.Node.prototype
* @param {Number} level between 0 and 1
* @returns {Number}
*/
/**
* get quantization levels. Sets the number of unique levels for each color
* channel. 2 is the minimum, 255 is the maximum. For Kinetic.Filters.Levels
* @name setQuantizationLevels
* @method
* @memberof Kinetic.Image.prototype
*/
})();

View File

@ -93,8 +93,8 @@
<script src="unit/filters/Pixelate-test.js"></script>
<script src="unit/filters/Noise-test.js"></script>
<script src="unit/filters/Threshold-test.js"></script>
<!--<script src="unit/filters/Levels-test.js"></script>
<script src="unit/filters/Flip-test.js"></script>
<script src="unit/filters/Levels-test.js"></script>
<!--<script src="unit/filters/Flip-test.js"></script>
<script src="unit/filters/Mirror-test.js"></script>
<script src="unit/filters/Sepia-test.js"></script>
-->

View File

@ -1,131 +1,4 @@
suite('Levels', function () {
// ======================================================
test('4 levels', function (done) {
var stage = addStage();
var shapesLayer = new Kinetic.Layer();
// The important line!
shapesLayer.on('draw', function () {
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width/2,this.getCanvas().height);
var scratchData = this.getContext().createImageData(imageData); // only size copied
Kinetic.Filters.Levels(imageData,scratchData,{quantizationLevels:4});
this.getContext().putImageData(scratchData,0,0);
});
var triangle = new Kinetic.RegularPolygon({
x: stage.getWidth() / 4,
y: stage.getHeight() / 2,
sides: 3,
radius: 80,
fillRadialGradientStartPoint: 0,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndPoint: 0,
fillRadialGradientEndRadius: 70,
fillRadialGradientColorStops: [0, '#881111', 0.5, '#888811', 1, '#000088'],
stroke: 'black',
strokeWidth: 4,
draggable: true
});
var circle = new Kinetic.Circle({
x: 3 * stage.getWidth() / 4,
y: stage.getHeight() / 2,
radius: 70,
fill: '#880000',
stroke: 'black',
strokeWidth: 4,
draggable: true,
id: 'myCircle'
});
for( var i=0; i<10; i+=1 ){
for( var j=0; j<10; j+=1 ){
var rect = new Kinetic.Rect({
x: i/10*stage.getWidth(),
y: j/10*stage.getHeight(),
width: stage.getWidth()/10,
height: stage.getHeight()/10,
fill: (i+j)%2===0?'#FF0000':'#FFFF00',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
shapesLayer.add(rect);
}
}
shapesLayer.add(circle);
shapesLayer.add(triangle);
stage.add(shapesLayer);
done();
});
// ======================================================
test('8 levels', function (done) {
var stage = addStage();
var shapesLayer = new Kinetic.Layer();
// The important line!
shapesLayer.on('draw', function () {
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width/2,this.getCanvas().height);
var scratchData = this.getContext().createImageData(imageData); // only size copied
Kinetic.Filters.Levels(imageData,scratchData,{quantizationLevels:8});
this.getContext().putImageData(scratchData,0,0);
});
var triangle = new Kinetic.RegularPolygon({
x: stage.getWidth() / 4,
y: stage.getHeight() / 2,
sides: 3,
radius: 80,
fillRadialGradientStartPoint: 0,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndPoint: 0,
fillRadialGradientEndRadius: 70,
fillRadialGradientColorStops: [0, '#881111', 0.5, '#888811', 1, '#000088'],
stroke: 'black',
strokeWidth: 4,
draggable: true
});
var circle = new Kinetic.Circle({
x: 3 * stage.getWidth() / 4,
y: stage.getHeight() / 2,
radius: 70,
fill: '#880000',
stroke: 'black',
strokeWidth: 4,
draggable: true,
id: 'myCircle'
});
for( var i=0; i<10; i+=1 ){
for( var j=0; j<10; j+=1 ){
var rect = new Kinetic.Rect({
x: i/10*stage.getWidth(),
y: j/10*stage.getHeight(),
width: stage.getWidth()/10,
height: stage.getHeight()/10,
fill: (i+j)%2===0?'#FF0000':'#FFFF00',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
shapesLayer.add(rect);
}
}
shapesLayer.add(circle);
shapesLayer.add(triangle);
stage.add(shapesLayer);
done();
});
// ======================================================
test('on image tween', function(done) {
@ -145,15 +18,16 @@ suite('Levels', function () {
layer.add(darth);
stage.add(layer);
darth.setFilter(Kinetic.Filters.Levels);
darth.setQuantizationLevels(16);
darth.cache();
darth.filters([Kinetic.Filters.Levels]);
darth.level(0.2);
layer.draw();
var tween = new Kinetic.Tween({
node: darth,
duration: 5.0,
quantizationLevels: 2,
easing: Kinetic.Easings.EaseInOut
duration: 1.0,
level: 0,
easing: Kinetic.Easings.Linear
});
darth.on('mouseover', function() {