Restored Sequencer Module Structure

This commit is contained in:
Chinmay Pandhare
2017-06-18 12:03:18 +05:30
parent f13da0fb19
commit ba4863c201
8 changed files with 104 additions and 77 deletions

View File

@@ -21,45 +21,60 @@ It is also for prototyping some other related ideas:
* cascading changes -- change an earlier step's settings, and see those changes affect later steps
* "small modules"-based extensibility: see [Contributing](#contributing), below
## Usage
Examples:
## Examples:
* [Basic example](https://jywarren.github.io/image-sequencer/)
* [NDVI example](https://jywarren.github.io/image-sequencer/examples/ndvi/) - related to [Infragram.org](http://infragram.org)
Using the library:
## Using the library:
### Initializing the Sequencer
The Image Sequencer Library exports a function ImageSequencer which initializes a sequencer.
```js
var sequencer = ImageSequencer();
```
### Loading Images into the Sequencer
Image Sequencer has an array of images which gets stored in `sequencer.images` in this case.
Images can be loaded into this array by the method `loadImages`.
loadImages accepts 1, 2, or 3 parameters.
3/2 parameters :
```js
sequencer.loadImages(image_name,image_src,optional_callback);
```
1/2 parameters (JSON) :
```js
sequencer.loadImages({
* 3/2 parameters :
```js
sequencer.loadImages(image_name,
image_src,optional_callback);
```
* 1/2 parameters (JSON) :
```js
sequencer.loadImages({
image_name_1: image_src,
image_name_2: image_src,
...
}, optional_callback);
```
}, optional_callback);
```
### Adding Steps on Images
After loading the image, we can add modules to the image using the addSteps method.
The options argument (object) is an optional parameter to pass in arguments to the module.
In all the following examples, `image_name` and `module_name` may be a string or an array of strings.
```js
sequencer.addSteps(image_name,module_name,optional_options);
```
If no Image Name is specified, the module is added to **all** images.
```js
sequencer.addSteps(module_name,optional_options);
```
All this can be passed in as JSON:
```js
sequencer.addSteps({
image_name: {name: module_name, o: optional_options},
@@ -68,26 +83,36 @@ sequencer.addSteps({
});
```
### Running the Sequencer
After adding the steps, now we must generate output for each of the step via the `run` method.
The `run` method accepts parameters `image` and `from`. `from` is the index from where the function starts generating output. By default, it will run across all the steps. (from = 1) If no image is specified, the sequencer will be run over all the images.
The `run` method accepts parameters `image` and `from`.
`from` is the index from where the function starts generating output. By default, it will run across all the steps. (from = 1) If no image is specified, the sequencer will be run over all the images.
```js
sequencer.run(); //All images from first step
```
```js
sequencer.run(image,from); //Image 'image' from 'from'
```
image may either be an array or a string.
An optional callback may also be passed.
### Removing Steps from an Image
Steps can be removed using the `removeSteps` method. It accepts `image` and `index` as parameters.
Either, both, or none of them can be an array. JSON input is also accepted. This method automatically triggers the `run` method as a callback.
Either, both, or none of them can be an array. JSON input is also accepted.
```js
sequencer.removeSteps("image",[steps]);
```
```js
sequencer.removeSteps("image",step);
```
```js
sequencer.removeSteps({
image: [steps],
@@ -96,6 +121,8 @@ sequencer.removeSteps({
});
```
### Inserting steps on an image
Steps can be inserted using the `insertSteps` method. It accepts `image`, `index`, `module_name` and `optional_options` as parameters. `image` may be an array. `optional_options` is an object. The rest are literals. JSON Input is supported too. If no image is provided, Steps will be inserted on all images. Indexes can be negative. Negative sign with an index means that counting will be done in reverse order. If the index is out of bounds, the counting will wrap in the original direction of counting.
```js
sequencer.insertSteps("image",index,"module_name",o);
@@ -126,19 +153,28 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
To add a module to Image Sequencer, it must have the following method; you can wrap an existing module to add them:
* `module.draw(image)`
* `module.draw()`
The `draw()` method should accept an `image` parameter, which will be a native JavaScript image object (i.e. `new Image()`).
The `draw(input,callback)` method should accept an `input` parameter, which will be an object of the form:
The draw method must, when it is complete, pass the output image to the method `options.output(image)`, which will send the output to the next module in the chain. For example:
```js
input = {
src: "datauri here",
format: "jpeg/png/etc"
}
```
The `image` object is essentially the output of the previous step.
The draw method must, when it is complete, pass the output image to the method `this.output = modified_input`, which will send the output to the next module in the chain. For example:
```js
function draw(image) {
// do some stuff with the image
options.output(image);
this.output = image;
callback();
}
```

View File

@@ -2,10 +2,10 @@ console.log('\x1b[31m%s\x1b[0m',"This is the output of the module");
require('./src/ImageSequencer');
sequencer = ImageSequencer();
sequencer.loadImages({red:'examples/red.jpg'},function(){
sequencer.addSteps(['do-nothing','do-nothing','do-nothing']);
sequencer.run();
sequencer.addSteps(['do-nothing','do-nothing-pix','do-nothing-pix','ndvi-red']);
sequencer.removeSteps(1);
sequencer.insertSteps({
red: [{index: -1, name: 'do-nothing', o:{}}]
});
sequencer.run();
});

View File

@@ -58,9 +58,10 @@ ImageSequencer = function ImageSequencer(options) {
o.container = o_.container || options.selector;
o.image = image;
var module = modules[name](o);
var module = modules[name].call(this.images,o);
images[image].steps.push(module);
function defaultSetupModule() {
if (options.ui && options.ui!="none") module.options.ui = options.ui({
selector: o.selector,
@@ -160,7 +161,7 @@ ImageSequencer = function ImageSequencer(options) {
for (i in indices)
removeStep(img,indices[i]);
}
this.run(run)
// this.run(run); // This is creating problems
}
function insertStep(image, index, name, o) {
@@ -242,28 +243,25 @@ ImageSequencer = function ImageSequencer(options) {
} // end if argument is object
}
this.run(run)
// this.run(run); // This is Creating issues
}
function run(t_image,t_from) {
log('\x1b[32m%s\x1b[0m',"Running the Sequencer!");
this_ = this;
runimg = {};
json_q = {};
args = [];
for (var arg in arguments) args.push(copy(arguments[arg]));
for (var arg in args)
if(objTypeOf(args[arg]) == "Function")
var callback = args.splice(arg,1)[0];
for (image in images) {
runimg[image] = 0;
}
function drawStep(drawarray,pos) {
if(pos==drawarray.length) if(objTypeOf(callback)=='Function') callback();
if(pos>=drawarray.length) return true;
image = drawarray[pos].image;
i = drawarray[pos].i;
images[image].steps[i].draw.call(this_,function(){
input = images[image].steps[i-1].output;
images[image].steps[i].draw(copy(input),function(){
drawStep(drawarray,++pos);
});
}
@@ -279,6 +277,11 @@ ImageSequencer = function ImageSequencer(options) {
drawStep(drawarray,0);
}
function filter(json_q){
for (image in json_q) {
if (json_q[image]==0 && this_.images[image].steps.length==1)
delete json_q[image];
else json_q[image]++;
}
for (image in json_q) {
prevstep = images[image].steps[json_q[image]-1];
while (typeof(prevstep) == "undefined" || typeof(prevstep.output) == "undefined") {

View File

@@ -4,26 +4,17 @@
module.exports = function DoNothing(options) {
options = options || {};
options.title = "Do Nothing";
this_ = this;
var output
var image;
var output;
function draw(callback) {
step = require('./_Step')(this,options);
newdata = step[0];
pos = step[1];
thisimage.steps[pos].output = {src:newdata.src,format:newdata.format};
function draw(input,callback) {
this.output = input;
callback();
}
function get() {
return image;
}
return {
options: options,
draw: draw,
get: get,
output: output
}
}

View File

@@ -6,23 +6,22 @@ module.exports = function GreenChannel(options) {
options = options || {};
options.title = "Green channel only";
options.description = "Displays only the green channel of an image";
var output;
//function setup() {} // optional
function draw(callback) {
step = require('./_Step')(this,options);
newdata = step[0];
pos = step[1];
function draw(input,callback) {
this_ = this;
function changePixel(r, g, b, a) {
return [r, g, b, a];
}
function output(image,datauri,mimetype){
images[image].steps[pos].output = {src:datauri,format:mimetype}
this_.output = {src:datauri,format:mimetype}
}
return require('./PixelManipulation.js')(newdata, {
return require('./PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
format: newdata.format,
format: input.format,
image: options.image,
callback: callback
});
@@ -31,6 +30,7 @@ module.exports = function GreenChannel(options) {
return {
options: options,
//setup: setup, // optional
draw: draw
draw: draw,
output: output
}
}

View File

@@ -6,23 +6,22 @@ module.exports = function GreenChannel(options) {
options = options || {};
options.title = "Green channel only";
options.description = "Displays only the green channel of an image";
var output;
//function setup() {} // optional
function draw(callback) {
step = require('./_Step')(this,options);
newdata = step[0];
pos = step[1];
function draw(input,callback) {
this_ = this;
function changePixel(r, g, b, a) {
return [0, g, 0, a];
}
function output(image,datauri,mimetype){
images[image].steps[pos].output = {src:datauri,format:mimetype}
this_.output = {src:datauri,format:mimetype}
}
return require('./PixelManipulation.js')(newdata, {
return require('./PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
format: newdata.format,
format: input.format,
image: options.image,
callback: callback
});
@@ -31,6 +30,7 @@ module.exports = function GreenChannel(options) {
return {
options: options,
//setup: setup, // optional
draw: draw
draw: draw,
output: output
}
}

View File

@@ -5,24 +5,23 @@ module.exports = function NdviRed(options) {
options = options || {};
options.title = "NDVI for red-filtered cameras (blue is infrared)";
var output;
//function setup() {} // optional
function draw(callback) {
step = require('./_Step')(this,options);
newdata = step[0];
pos = step[1];
function draw(input,callback) {
this_ = this;
function changePixel(r, g, b, a) {
var ndvi = 255 * (b - r) / (1.00 * b + r);
return [ndvi, ndvi, ndvi, a];
}
function output(image,datauri,mimetype){
images[image].steps[pos].output = {src:datauri,format:mimetype}
this_.output = {src:datauri,format:mimetype}
}
return require('./PixelManipulation.js')(newdata, {
return require('./PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
format: newdata.format,
format: input.format,
image: options.image,
callback: callback
});

View File

@@ -1,11 +1,9 @@
module.exports = function(ref,options) {
module.exports = function(ref,image,pos) {
images = ref.images;
thisimage = images[options.image];
for (i in thisimage.steps){
if (thisimage.steps[i].options.id == options.id) pos = i;
thisimage = images[image];
var thisstep = thisimage[pos];
console.log(thisstep);
return function(img) {
thisstep.output = img;
}
olddata = thisimage.steps[pos-1].output;
if (typeof(olddata) == 'undefined') return false;
var newdata = JSON.parse(JSON.stringify(olddata));
return [newdata,pos];
}