Merge #86 from publiclab/image-sequencer

This commit is contained in:
Chinmay Pandhare
2017-07-29 04:13:04 +05:30
17 changed files with 332 additions and 259 deletions

2
.gitignore vendored
View File

@@ -34,3 +34,5 @@ node_modules
*.swp *.swp
todo.txt todo.txt
test.js
output.txt

View File

@@ -13,17 +13,18 @@ Any module must look like this :
module.exports = function ModuleName(options,UI) { module.exports = function ModuleName(options,UI) {
options = options || {}; options = options || {};
options.title = "Title of the Module"; options.title = "Title of the Module";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
var output = /*do something with the input*/ ; var output = /*do something with the input*/ ;
this.output = output; this.output = output;
options.step.output = output.src;
callback(); callback();
UI.onComplete(this.output.src); UI.onComplete(options.step);
} }
return { return {
@@ -65,21 +66,19 @@ constant definitions must be done **outside** the `draw()` method's definition.
step has been "drawn". step has been "drawn".
When you have done your calculations and produced an image output, you are required When you have done your calculations and produced an image output, you are required
to set `this.output` to an object similar to what the input object was, and call to set `this.output` to an object similar to what the input object was, call
`callback()`. `callback()`, and set `options.step.output` equal to the output DataURL
### UI Methods ### UI Methods
The module is responsible to emit various events for the UI to capture. There are The module is responsible to emit various events for the UI to capture. There are
four events in all: four events in all:
* `UI.onSetup()` must be emitted when the module is added. So it must be emitted * `UI.onSetup(options.step)` must be emitted when the module is added. So it must be emitted outside the draw method's definition as shown above.
outside the draw method's definition as shown above. * `UI.onDraw(options.step)` must be emitted whenever the `draw()` method is called. So it should ideally be the first line of the definition of the `draw` method.
* `UI.onDraw()` must be emitted whenever the `draw()` method is called. So it should * `UI.onComplete(options.step)` must be emitted whenever the output of a draw call
ideally be the first line of the definition of the `draw` method.
* `UI.onComplete(output_src)` must be emitted whenever the output of a draw call
is ready. An argument, that is the DataURL of the output image must be passed in. is ready. An argument, that is the DataURL of the output image must be passed in.
* `UI.onRemove()` is emitted automatically and the module should not emit it. * `UI.onRemove(options.step)` is emitted automatically and the module should not emit it.
To add a module to Image Sequencer, it must have the following method; you can wrap an existing module to add them: To add a module to Image Sequencer, it must have the following method; you can wrap an existing module to add them:

View File

@@ -370,10 +370,10 @@ How to define these functions:
```js ```js
sequencer.setUI({ sequencer.setUI({
onSetup: function() {}, onSetup: function(step) {},
onDraw: function() {}, onDraw: function(step) {},
onComplete: function(output) {}, onComplete: function(step) {},
onRemove: function() {} onRemove: function(step) {}
}); });
``` ```
@@ -383,18 +383,40 @@ the `setUI` method will only affect the modules added after `setUI` is called.
The `onComplete` event is passed on the output of the module. The `onComplete` event is passed on the output of the module.
In the scope of all these events, the following variables are present, which Image Sequencer provides a namespace `step` for the purpose of UI Creation in
may be used in generating the UI: the scope of these definable function. This namespace has the following
* The object `identity` predefined properties:
```
identity = {
stepName: "Name of the Step",
stepID: "A unique ID given to the step",
imageName: "The name of the image to which the step is added."
}
```
* The variable `options.inBrowser` which is a Boolean and is `true` if the client is a browser and `false` otherwise.
Note: `identity.imageName` is the "name" of that particular image. This name can be specified * `step.name` : (String) Name of the step
while loading the image via `sequencer.loadImage("name","SRC")`. If not specified, * `step.ID` : (Number) An ID given to every step of the sequencer, unique throughout.
the name of a loaded image defaults to a name like "image1", "image2", et cetra. * `step.imageName` : (String) Name of the image the step is applied to.
* `step.output` : (DataURL String) Output of the step.
* `step.inBrowser` : (Boolean) Whether the client is a browser or not
In addition to these, one might define their own properties, which shall be
accessible across all the event scopes of that step.
For example :
```js
sequencer.setUI({
onSetup: function(step){
// Create new property "step.image"
step.image = document.createElement('img');
document.body.append(step.image);
},
onComplete: function(step){
// Access predefined "step.output" and user-defined "step.image"
step.image.src = step.output;
},
onRemove: function(step){
// Access user-defined "step.image"
step.image.remove();
}
});
```
Note: `identity.imageName` is the "name" of that particular image. This name can
be specified while loading the image via `sequencer.loadImage("name","SRC")`. If
not specified, the name of a loaded image defaults to a name like "image1",
"image2", et cetra.

View File

@@ -34881,11 +34881,14 @@ function AddStep(ref, image, name, o) {
o.image = image; o.image = image;
o.inBrowser = ref.options.inBrowser; o.inBrowser = ref.options.inBrowser;
var UI = ref.UI({ o.step = {
stepName: o.name, name: o.name,
stepID: o.number, ID: o.number,
imageName: o.image imageName: o.image,
}); inBrowser: ref.options.inBrowser,
ui: ref.options.ui
};
var UI = ref.events;
var module = ref.modules[name](o,UI); var module = ref.modules[name](o,UI);
ref.images[image].steps.push(module); ref.images[image].steps.push(module);
@@ -35107,9 +35110,7 @@ ImageSequencer = function ImageSequencer(options) {
formatInput = require('./FormatInput'), formatInput = require('./FormatInput'),
images = {}, images = {},
inputlog = [], inputlog = [],
UI; events = require('./UserInterface')();
setUI();
// if in browser, prompt for an image // if in browser, prompt for an image
// if (options.imageSelect || options.inBrowser) addStep('image-select'); // if (options.imageSelect || options.inBrowser) addStep('image-select');
@@ -35134,7 +35135,8 @@ ImageSequencer = function ImageSequencer(options) {
function removeStep(image,index) { function removeStep(image,index) {
//remove the step from images[image].steps and redraw remaining images //remove the step from images[image].steps and redraw remaining images
if(index>0) { if(index>0) {
images[image].steps[index].UI.onRemove(); thisStep = images[image].steps[index];
thisStep.UI.onRemove(thisStep.options.step);
images[image].steps.splice(index,1); images[image].steps.splice(index,1);
} }
//tell the UI a step has been removed //tell the UI a step has been removed
@@ -35237,9 +35239,8 @@ ImageSequencer = function ImageSequencer(options) {
return require('./ReplaceImage')(this,selector,steps); return require('./ReplaceImage')(this,selector,steps);
} }
function setUI(_UI) { function setUI(UI) {
UI = require('./UserInterface')(_UI,options); this.events = require('./UserInterface')(UI);
return UI;
} }
return { return {
@@ -35249,7 +35250,7 @@ ImageSequencer = function ImageSequencer(options) {
inputlog: inputlog, inputlog: inputlog,
modules: modules, modules: modules,
images: images, images: images,
UI: UI, events: events,
//user functions //user functions
loadImages: loadImages, loadImages: loadImages,
@@ -35283,11 +35284,14 @@ function InsertStep(ref, image, index, name, o) {
if(index==-1) index = ref.images[image].steps.length; if(index==-1) index = ref.images[image].steps.length;
var UI = ref.UI({ o.step = {
stepName: o.name, name: o.name,
stepID: o.number, ID: o.number,
imageName: o.image imageName: o.image,
}); inBrowser: ref.options.inBrowser,
ui: ref.options.ui
};
var UI = ref.events;
var module = ref.modules[name](o,UI); var module = ref.modules[name](o,UI);
ref.images[image].steps.splice(index,0,module); ref.images[image].steps.splice(index,0,module);
@@ -35345,27 +35349,37 @@ function LoadImage(ref, name, src, main_callback) {
} }
function loadImage(name, src) { function loadImage(name, src) {
var step = {
name: "load-image",
ID: ref.options.sequencerCounter++,
imageName: name,
inBrowser: ref.options.inBrowser,
ui: ref.options.ui
};
var image = { var image = {
src: src, src: src,
steps: [{ steps: [{
options: { options: {
id: ref.options.sequencerCounter++, id: step.ID,
name: "load-image", name: "load-image",
title: "Load Image" title: "Load Image",
step: step
}, },
UI: ref.UI({ UI: ref.events,
stepName: "load-image",
stepID: ref.options.sequencerCounter++,
imageName: name
}),
draw: function() { draw: function() {
UI.onDraw(options.step);
if(arguments.length==1){ if(arguments.length==1){
this.output = CImage(arguments[0]); this.output = CImage(arguments[0]);
options.step.output = this.output;
UI.onComplete(options.step);
return true; return true;
} }
else if(arguments.length==2) { else if(arguments.length==2) {
this.output = CImage(arguments[0]); this.output = CImage(arguments[0]);
options.step.output = this.output;
arguments[1](); arguments[1]();
UI.onComplete(options.step);
return true; return true;
} }
return false; return false;
@@ -35374,11 +35388,14 @@ function LoadImage(ref, name, src, main_callback) {
}; };
CImage(src, function(datauri) { CImage(src, function(datauri) {
var output = makeImage(datauri); var output = makeImage(datauri);
image.steps[0].output = output;
ref.images[name] = image; ref.images[name] = image;
ref.images[name].steps[0].UI.onSetup(); var loadImageStep = ref.images[name].steps[0];
ref.images[name].steps[0].UI.onDraw(); loadImageStep.output = output;
ref.images[name].steps[0].UI.onComplete(image.steps[0].output.src); loadImageStep.options.step.output = loadImageStep.output.src;
loadImageStep.UI.onSetup(loadImageStep.options.step);
loadImageStep.UI.onDraw(loadImageStep.options.step);
loadImageStep.UI.onComplete(loadImageStep.options.step);
main_callback(); main_callback();
return true; return true;
}); });
@@ -35492,76 +35509,70 @@ module.exports = Run;
},{}],127:[function(require,module,exports){ },{}],127:[function(require,module,exports){
/* /*
* Default UI for each image-sequencer module * User Interface Handling Module
*/ */
module.exports = function UserInterface(UI,options) {
return function userInterface(identity) { module.exports = function UserInterface(events = {}) {
var UI = UI || {}; events.onSetup = events.onSetup || function(step) {
if(step.ui == false) {
UI.onSetup = UI.onSetup || function() {
if(options.ui == false) {
// No UI // No UI
}
else if(options.inBrowser) {
// Create and append an HTML Element
console.log("Added Step \""+identity.stepName+"\" to \""+identity.imageName+"\".");
}
else {
// Create a NodeJS Object
console.log('\x1b[36m%s\x1b[0m',"Added Step \""+identity.stepName+"\" to \""+identity.imageName+"\".");
}
} }
else if(step.inBrowser) {
UI.onDraw = UI.onDraw || function() { // Create and append an HTML Element
if (options.ui == false) { console.log("Added Step \""+step.name+"\" to \""+step.imageName+"\".");
// No UI
}
else if(options.inBrowser) {
// Overlay a loading spinner
console.log("Drawing Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
else {
// Don't do anything
console.log('\x1b[33m%s\x1b[0m',"Drawing Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
} }
else {
UI.onComplete = UI.onComplete || function(output) { // Create a NodeJS Object
if (options.ui == false) { console.log('\x1b[36m%s\x1b[0m',"Added Step \""+step.name+"\" to \""+step.imageName+"\".");
// No UI
}
else if(options.inBrowser) {
// Update the DIV Element
// Hide the laoding spinner
console.log("Drawn Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
else {
// Update the NodeJS Object
console.log('\x1b[32m%s\x1b[0m',"Drawn Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
} }
UI.onRemove = UI.onRemove || function(callback) {
if(options.ui == false){
// No UI
}
else if(options.inBrowser) {
// Remove the DIV Element
console.log("Removing Step \""+identity.stepName+"\" of \""+identity.imageName+"\".");
}
else {
// Delete the NodeJS Object
console.log('\x1b[31m%s\x1b[0m',"Removing Step \""+identity.stepName+"\" of \""+identity.imageName+"\".");
}
}
return UI;
} }
events.onDraw = events.onDraw || function(step) {
if (step.ui == false) {
// No UI
}
else if(step.inBrowser) {
// Overlay a loading spinner
console.log("Drawing Step \""+step.name+"\" on \""+step.imageName+"\".");
}
else {
// Don't do anything
console.log('\x1b[33m%s\x1b[0m',"Drawing Step \""+step.name+"\" on \""+step.imageName+"\".");
}
}
events.onComplete = events.onComplete || function(step) {
if (step.ui == false) {
// No UI
}
else if(step.inBrowser) {
// Update the DIV Element
// Hide the laoding spinner
console.log("Drawn Step \""+step.name+"\" on \""+step.imageName+"\".");
}
else {
// Update the NodeJS Object
console.log('\x1b[32m%s\x1b[0m',"Drawn Step \""+step.name+"\" on \""+step.imageName+"\".");
}
}
events.onRemove = events.onRemove || function(step) {
if(step.ui == false){
// No UI
}
else if(step.inBrowser) {
// Remove the DIV Element
console.log("Removing Step \""+step.name+"\" of \""+step.imageName+"\".");
}
else {
// Delete the NodeJS Object
console.log('\x1b[31m%s\x1b[0m',"Removing Step \""+step.name+"\" of \""+step.imageName+"\".");
}
}
return events;
} }
},{}],128:[function(require,module,exports){ },{}],128:[function(require,module,exports){
@@ -35622,12 +35633,12 @@ module.exports = function Crop(input,options,callback) {
module.exports = function CropModule(options,UI) { module.exports = function CropModule(options,UI) {
options = options || {}; options = options || {};
options.title = "Crop Image"; options.title = "Crop Image";
UI.onSetup(); UI.onSetup(options.step);
var output var output
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
require('./Crop')(input,options,function(out,format){ require('./Crop')(input,options,function(out,format){
@@ -35635,7 +35646,8 @@ module.exports = function Crop(input,options,callback) {
src: out, src: out,
format: format format: format
} }
UI.onComplete(out); options.step.output = out;
UI.onComplete(options.step);
callback(); callback();
}); });
@@ -35657,14 +35669,17 @@ module.exports = function Crop(input,options,callback) {
module.exports = function DoNothing(options,UI) { module.exports = function DoNothing(options,UI) {
options = options || {}; options = options || {};
options.title = "Do Nothing"; options.title = "Do Nothing";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
this.output = input; this.output = input;
options.step.output = this.output.src;
callback(); callback();
UI.onComplete(this.output.src); UI.onComplete(options.step);
} }
return { return {
@@ -35683,12 +35698,12 @@ module.exports = function DoNothingPix(options,UI) {
options = options || {}; options = options || {};
options.title = "Do Nothing with pixels"; options.title = "Do Nothing with pixels";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -35696,7 +35711,8 @@ module.exports = function DoNothingPix(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype} step.output = {src:datauri,format:mimetype}
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
@@ -35720,14 +35736,16 @@ module.exports = function DoNothingPix(options,UI) {
/* /*
* Creates Fisheye Effect * Creates Fisheye Effect
*/ */
module.exports = function DoNothing(options) { module.exports = function DoNothing(options,UI) {
options = options || {}; options = options || {};
options.title = "Fisheye GL"; options.title = "Fisheye GL";
var output; var output;
UI.onSetup(options.step);
require('fisheyegl'); require('fisheyegl');
function draw(input,callback) { function draw(input,callback) {
this_ = this; UI.onDraw(options.step);
const step = this;
if (!options.inBrowser) { // This module is only for browser if (!options.inBrowser) { // This module is only for browser
this.output = input; this.output = input;
callback(); callback();
@@ -35754,8 +35772,10 @@ module.exports = function DoNothing(options) {
distorter.fov.y = options.y || distorter.fov.y; distorter.fov.y = options.y || distorter.fov.y;
distorter.setImage(input.src,function(){ distorter.setImage(input.src,function(){
this_.output = {src: canvas.toDataURL(), format: input.format}; step.output = {src: canvas.toDataURL(), format: input.format};
options.step.output = step.output.src;
callback(); callback();
UI.onComplete(options.step);
}); });
} }
@@ -35764,7 +35784,8 @@ module.exports = function DoNothing(options) {
return { return {
options: options, options: options,
draw: draw, draw: draw,
output: output output: output,
UI: UI
} }
} }
@@ -35777,12 +35798,12 @@ module.exports = function GreenChannel(options,UI) {
options = options || {}; options = options || {};
options.title = "Green channel only"; options.title = "Green channel only";
options.description = "Displays only the green channel of an image"; options.description = "Displays only the green channel of an image";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -35790,7 +35811,8 @@ module.exports = function GreenChannel(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
@@ -35820,14 +35842,14 @@ module.exports = function GreenChannel(options,UI) {
options = options || {}; options = options || {};
options.title = "Invert Colors"; options.title = "Invert Colors";
options.description = "Inverts the colors of the image"; options.description = "Inverts the colors of the image";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
//function setup() {} // optional //function setup() {} // optional
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -35835,7 +35857,8 @@ module.exports = function GreenChannel(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
@@ -35864,12 +35887,12 @@ module.exports = function NdviRed(options,UI) {
options = options || {}; options = options || {};
options.title = "NDVI for red-filtered cameras (blue is infrared)"; options.title = "NDVI for red-filtered cameras (blue is infrared)";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -35879,7 +35902,8 @@ module.exports = function NdviRed(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
@@ -35904,12 +35928,12 @@ module.exports = function SegmentedColormap(options,UI) {
options = options || {}; options = options || {};
options.title = "Segmented Colormap"; options.title = "Segmented Colormap";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -35920,7 +35944,8 @@ module.exports = function SegmentedColormap(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,

View File

@@ -9,11 +9,14 @@ function AddStep(ref, image, name, o) {
o.image = image; o.image = image;
o.inBrowser = ref.options.inBrowser; o.inBrowser = ref.options.inBrowser;
var UI = ref.UI({ o.step = {
stepName: o.name, name: o.name,
stepID: o.number, ID: o.number,
imageName: o.image imageName: o.image,
}); inBrowser: ref.options.inBrowser,
ui: ref.options.ui
};
var UI = ref.events;
var module = ref.modules[name](o,UI); var module = ref.modules[name](o,UI);
ref.images[image].steps.push(module); ref.images[image].steps.push(module);

View File

@@ -42,9 +42,7 @@ ImageSequencer = function ImageSequencer(options) {
formatInput = require('./FormatInput'), formatInput = require('./FormatInput'),
images = {}, images = {},
inputlog = [], inputlog = [],
UI; events = require('./UserInterface')();
setUI();
// if in browser, prompt for an image // if in browser, prompt for an image
// if (options.imageSelect || options.inBrowser) addStep('image-select'); // if (options.imageSelect || options.inBrowser) addStep('image-select');
@@ -69,7 +67,8 @@ ImageSequencer = function ImageSequencer(options) {
function removeStep(image,index) { function removeStep(image,index) {
//remove the step from images[image].steps and redraw remaining images //remove the step from images[image].steps and redraw remaining images
if(index>0) { if(index>0) {
images[image].steps[index].UI.onRemove(); thisStep = images[image].steps[index];
thisStep.UI.onRemove(thisStep.options.step);
images[image].steps.splice(index,1); images[image].steps.splice(index,1);
} }
//tell the UI a step has been removed //tell the UI a step has been removed
@@ -172,9 +171,8 @@ ImageSequencer = function ImageSequencer(options) {
return require('./ReplaceImage')(this,selector,steps); return require('./ReplaceImage')(this,selector,steps);
} }
function setUI(_UI) { function setUI(UI) {
UI = require('./UserInterface')(_UI,options); this.events = require('./UserInterface')(UI);
return UI;
} }
return { return {
@@ -184,7 +182,7 @@ ImageSequencer = function ImageSequencer(options) {
inputlog: inputlog, inputlog: inputlog,
modules: modules, modules: modules,
images: images, images: images,
UI: UI, events: events,
//user functions //user functions
loadImages: loadImages, loadImages: loadImages,

View File

@@ -10,11 +10,14 @@ function InsertStep(ref, image, index, name, o) {
if(index==-1) index = ref.images[image].steps.length; if(index==-1) index = ref.images[image].steps.length;
var UI = ref.UI({ o.step = {
stepName: o.name, name: o.name,
stepID: o.number, ID: o.number,
imageName: o.image imageName: o.image,
}); inBrowser: ref.options.inBrowser,
ui: ref.options.ui
};
var UI = ref.events;
var module = ref.modules[name](o,UI); var module = ref.modules[name](o,UI);
ref.images[image].steps.splice(index,0,module); ref.images[image].steps.splice(index,0,module);

View File

@@ -44,27 +44,37 @@ function LoadImage(ref, name, src, main_callback) {
} }
function loadImage(name, src) { function loadImage(name, src) {
var step = {
name: "load-image",
ID: ref.options.sequencerCounter++,
imageName: name,
inBrowser: ref.options.inBrowser,
ui: ref.options.ui
};
var image = { var image = {
src: src, src: src,
steps: [{ steps: [{
options: { options: {
id: ref.options.sequencerCounter++, id: step.ID,
name: "load-image", name: "load-image",
title: "Load Image" title: "Load Image",
step: step
}, },
UI: ref.UI({ UI: ref.events,
stepName: "load-image",
stepID: ref.options.sequencerCounter++,
imageName: name
}),
draw: function() { draw: function() {
UI.onDraw(options.step);
if(arguments.length==1){ if(arguments.length==1){
this.output = CImage(arguments[0]); this.output = CImage(arguments[0]);
options.step.output = this.output;
UI.onComplete(options.step);
return true; return true;
} }
else if(arguments.length==2) { else if(arguments.length==2) {
this.output = CImage(arguments[0]); this.output = CImage(arguments[0]);
options.step.output = this.output;
arguments[1](); arguments[1]();
UI.onComplete(options.step);
return true; return true;
} }
return false; return false;
@@ -73,11 +83,14 @@ function LoadImage(ref, name, src, main_callback) {
}; };
CImage(src, function(datauri) { CImage(src, function(datauri) {
var output = makeImage(datauri); var output = makeImage(datauri);
image.steps[0].output = output;
ref.images[name] = image; ref.images[name] = image;
ref.images[name].steps[0].UI.onSetup(); var loadImageStep = ref.images[name].steps[0];
ref.images[name].steps[0].UI.onDraw(); loadImageStep.output = output;
ref.images[name].steps[0].UI.onComplete(image.steps[0].output.src); loadImageStep.options.step.output = loadImageStep.output.src;
loadImageStep.UI.onSetup(loadImageStep.options.step);
loadImageStep.UI.onDraw(loadImageStep.options.step);
loadImageStep.UI.onComplete(loadImageStep.options.step);
main_callback(); main_callback();
return true; return true;
}); });

View File

@@ -1,72 +1,66 @@
/* /*
* Default UI for each image-sequencer module * User Interface Handling Module
*/ */
module.exports = function UserInterface(UI,options) {
return function userInterface(identity) { module.exports = function UserInterface(events = {}) {
var UI = UI || {}; events.onSetup = events.onSetup || function(step) {
if(step.ui == false) {
UI.onSetup = UI.onSetup || function() {
if(options.ui == false) {
// No UI // No UI
}
else if(options.inBrowser) {
// Create and append an HTML Element
console.log("Added Step \""+identity.stepName+"\" to \""+identity.imageName+"\".");
}
else {
// Create a NodeJS Object
console.log('\x1b[36m%s\x1b[0m',"Added Step \""+identity.stepName+"\" to \""+identity.imageName+"\".");
}
} }
else if(step.inBrowser) {
UI.onDraw = UI.onDraw || function() { // Create and append an HTML Element
if (options.ui == false) { console.log("Added Step \""+step.name+"\" to \""+step.imageName+"\".");
// No UI
}
else if(options.inBrowser) {
// Overlay a loading spinner
console.log("Drawing Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
else {
// Don't do anything
console.log('\x1b[33m%s\x1b[0m',"Drawing Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
} }
else {
UI.onComplete = UI.onComplete || function(output) { // Create a NodeJS Object
if (options.ui == false) { console.log('\x1b[36m%s\x1b[0m',"Added Step \""+step.name+"\" to \""+step.imageName+"\".");
// No UI
}
else if(options.inBrowser) {
// Update the DIV Element
// Hide the laoding spinner
console.log("Drawn Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
else {
// Update the NodeJS Object
console.log('\x1b[32m%s\x1b[0m',"Drawn Step \""+identity.stepName+"\" on \""+identity.imageName+"\".");
}
} }
UI.onRemove = UI.onRemove || function(callback) {
if(options.ui == false){
// No UI
}
else if(options.inBrowser) {
// Remove the DIV Element
console.log("Removing Step \""+identity.stepName+"\" of \""+identity.imageName+"\".");
}
else {
// Delete the NodeJS Object
console.log('\x1b[31m%s\x1b[0m',"Removing Step \""+identity.stepName+"\" of \""+identity.imageName+"\".");
}
}
return UI;
} }
events.onDraw = events.onDraw || function(step) {
if (step.ui == false) {
// No UI
}
else if(step.inBrowser) {
// Overlay a loading spinner
console.log("Drawing Step \""+step.name+"\" on \""+step.imageName+"\".");
}
else {
// Don't do anything
console.log('\x1b[33m%s\x1b[0m',"Drawing Step \""+step.name+"\" on \""+step.imageName+"\".");
}
}
events.onComplete = events.onComplete || function(step) {
if (step.ui == false) {
// No UI
}
else if(step.inBrowser) {
// Update the DIV Element
// Hide the laoding spinner
console.log("Drawn Step \""+step.name+"\" on \""+step.imageName+"\".");
}
else {
// Update the NodeJS Object
console.log('\x1b[32m%s\x1b[0m',"Drawn Step \""+step.name+"\" on \""+step.imageName+"\".");
}
}
events.onRemove = events.onRemove || function(step) {
if(step.ui == false){
// No UI
}
else if(step.inBrowser) {
// Remove the DIV Element
console.log("Removing Step \""+step.name+"\" of \""+step.imageName+"\".");
}
else {
// Delete the NodeJS Object
console.log('\x1b[31m%s\x1b[0m',"Removing Step \""+step.name+"\" of \""+step.imageName+"\".");
}
}
return events;
} }

View File

@@ -16,12 +16,12 @@
module.exports = function CropModule(options,UI) { module.exports = function CropModule(options,UI) {
options = options || {}; options = options || {};
options.title = "Crop Image"; options.title = "Crop Image";
UI.onSetup(); UI.onSetup(options.step);
var output var output
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
require('./Crop')(input,options,function(out,format){ require('./Crop')(input,options,function(out,format){
@@ -29,7 +29,8 @@
src: out, src: out,
format: format format: format
} }
UI.onComplete(out); options.step.output = out;
UI.onComplete(options.step);
callback(); callback();
}); });

View File

@@ -4,14 +4,17 @@
module.exports = function DoNothing(options,UI) { module.exports = function DoNothing(options,UI) {
options = options || {}; options = options || {};
options.title = "Do Nothing"; options.title = "Do Nothing";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
this.output = input; this.output = input;
options.step.output = this.output.src;
callback(); callback();
UI.onComplete(this.output.src); UI.onComplete(options.step);
} }
return { return {

View File

@@ -5,12 +5,12 @@ module.exports = function DoNothingPix(options,UI) {
options = options || {}; options = options || {};
options.title = "Do Nothing with pixels"; options.title = "Do Nothing with pixels";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -18,7 +18,8 @@ module.exports = function DoNothingPix(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype} step.output = {src:datauri,format:mimetype}
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,

View File

@@ -1,14 +1,16 @@
/* /*
* Creates Fisheye Effect * Creates Fisheye Effect
*/ */
module.exports = function DoNothing(options) { module.exports = function DoNothing(options,UI) {
options = options || {}; options = options || {};
options.title = "Fisheye GL"; options.title = "Fisheye GL";
var output; var output;
UI.onSetup(options.step);
require('fisheyegl'); require('fisheyegl');
function draw(input,callback) { function draw(input,callback) {
this_ = this; UI.onDraw(options.step);
const step = this;
if (!options.inBrowser) { // This module is only for browser if (!options.inBrowser) { // This module is only for browser
this.output = input; this.output = input;
callback(); callback();
@@ -35,8 +37,10 @@ module.exports = function DoNothing(options) {
distorter.fov.y = options.y || distorter.fov.y; distorter.fov.y = options.y || distorter.fov.y;
distorter.setImage(input.src,function(){ distorter.setImage(input.src,function(){
this_.output = {src: canvas.toDataURL(), format: input.format}; step.output = {src: canvas.toDataURL(), format: input.format};
options.step.output = step.output.src;
callback(); callback();
UI.onComplete(options.step);
}); });
} }
@@ -45,6 +49,7 @@ module.exports = function DoNothing(options) {
return { return {
options: options, options: options,
draw: draw, draw: draw,
output: output output: output,
UI: UI
} }
} }

View File

@@ -6,12 +6,12 @@ module.exports = function GreenChannel(options,UI) {
options = options || {}; options = options || {};
options.title = "Green channel only"; options.title = "Green channel only";
options.description = "Displays only the green channel of an image"; options.description = "Displays only the green channel of an image";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -19,7 +19,8 @@ module.exports = function GreenChannel(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,

View File

@@ -6,14 +6,14 @@ module.exports = function GreenChannel(options,UI) {
options = options || {}; options = options || {};
options.title = "Invert Colors"; options.title = "Invert Colors";
options.description = "Inverts the colors of the image"; options.description = "Inverts the colors of the image";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
//function setup() {} // optional //function setup() {} // optional
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -21,7 +21,8 @@ module.exports = function GreenChannel(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,

View File

@@ -5,12 +5,12 @@ module.exports = function NdviRed(options,UI) {
options = options || {}; options = options || {};
options.title = "NDVI for red-filtered cameras (blue is infrared)"; options.title = "NDVI for red-filtered cameras (blue is infrared)";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -20,7 +20,8 @@ module.exports = function NdviRed(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,

View File

@@ -2,12 +2,12 @@ module.exports = function SegmentedColormap(options,UI) {
options = options || {}; options = options || {};
options.title = "Segmented Colormap"; options.title = "Segmented Colormap";
UI.onSetup(); UI.onSetup(options.step);
var output; var output;
function draw(input,callback) { function draw(input,callback) {
UI.onDraw(); UI.onDraw(options.step);
const step = this; const step = this;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -18,7 +18,8 @@ module.exports = function SegmentedColormap(options,UI) {
} }
function output(image,datauri,mimetype){ function output(image,datauri,mimetype){
step.output = {src:datauri,format:mimetype}; step.output = {src:datauri,format:mimetype};
UI.onComplete(datauri); options.step.output = datauri;
UI.onComplete(options.step);
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,