mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-06 08:20:04 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51524f747a | ||
|
|
b16b45afa8 | ||
|
|
39418da187 | ||
|
|
8547c60873 | ||
|
|
adc21ae843 | ||
|
|
2abf0fae09 | ||
|
|
711ae62ee3 | ||
|
|
4d75fb9640 | ||
|
|
5ac3ef008d | ||
|
|
98f913b32e | ||
|
|
c2756ffdbb |
218
CONTRIBUTING.md
218
CONTRIBUTING.md
@@ -12,6 +12,7 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
|
||||
* [Info File](#info-file)
|
||||
* [Ideas](#ideas)
|
||||
|
||||
****
|
||||
|
||||
## Contribution ideas
|
||||
|
||||
@@ -27,29 +28,30 @@ If you find a bug please list it here, and help us develop Image Sequencer by [o
|
||||
|
||||
Most contributions can happen in modules, rather than to core library code. Modules and their [corresponding info files](#info-file) are included into the library in this file: https://github.com/publiclab/image-sequencer/blob/master/src/Modules.js#L5-L7
|
||||
|
||||
Module names, descriptions, and parameters are set in the `info.json` file -- [see below](#info-file).
|
||||
|
||||
Any module must follow this basic format:
|
||||
|
||||
```js
|
||||
module.exports = function ModuleName(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Title of the Module";
|
||||
UI.onSetup(options.step);
|
||||
var output;
|
||||
|
||||
function draw(input,callback) {
|
||||
|
||||
UI.onDraw(options.step);
|
||||
UI.onDraw(options.step); // tell the UI to "draw"
|
||||
|
||||
var output = function(input){
|
||||
/* do something with the input */
|
||||
return input;
|
||||
}
|
||||
|
||||
this.output = output(input);
|
||||
this.output = output(input); // run the output and assign it to this.output
|
||||
options.step.output = output.src;
|
||||
callback();
|
||||
UI.onComplete(options.step);
|
||||
UI.onComplete(options.step); // tell UI we are done
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -60,13 +62,116 @@ module.exports = function ModuleName(options,UI) {
|
||||
}
|
||||
}
|
||||
```
|
||||
The default loading spinner can be optionally overriden with a custom progress object to draw progress on the CLI, following is a basic module format for the same
|
||||
|
||||
|
||||
### options
|
||||
|
||||
The object `options` stores some important information. This is how you can accept
|
||||
input from users. If you require a variable "x" from the user and the user passes
|
||||
it in, you will be able to access it as `options.x`.
|
||||
|
||||
Options also has some in-built properties. The `options.inBrowser` boolean denotes
|
||||
whether your module is being run on a browser.
|
||||
|
||||
### draw()
|
||||
|
||||
To add a module to Image Sequencer, it must have a `draw` method; you can wrap an existing module to add them:
|
||||
|
||||
* `module.draw(input, callback)`
|
||||
|
||||
The `draw` method should accept an `input` parameter, which will be an object of the form:
|
||||
|
||||
```js
|
||||
input = {
|
||||
src: "datauri of an image here",
|
||||
format: "jpeg/png/etc"
|
||||
}
|
||||
```
|
||||
|
||||
The draw method is run every time the step is `run` using `sequencer.run()`.
|
||||
So any calculations must go **into** the `draw()` method's definition.
|
||||
|
||||
What is not in the draw method, but is in the `module.exports` is executed only
|
||||
when the step is added. So whatever external npm modules are to be loaded, or
|
||||
constant definitions must be done **outside** the `draw()` method's definition.
|
||||
|
||||
`draw()` receives two arguments - `input` and `callback` :
|
||||
* `input` is an object which is essentially the output of the previous step.
|
||||
```js
|
||||
input = {
|
||||
src: "<$DataURL>",
|
||||
format: "<png|jpeg|gif>"
|
||||
}
|
||||
```
|
||||
* `callback` is a function which is responsible to tell the sequencer that the step has been "drawn".
|
||||
|
||||
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, call `callback()`, and set `options.step.output` equal to the output DataURL
|
||||
|
||||
* `progressObj` is an optional additional Object that can be passed in the format `draw(input, callback, progressObj)`, which handles the progress output; see [Progress reporting](#progress-reporting) below.
|
||||
|
||||
### UI Methods
|
||||
|
||||
The module is responsible for emitting various events for the UI to capture.
|
||||
|
||||
There are four events in all:
|
||||
|
||||
* `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.
|
||||
* `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.onComplete(options.step)` 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.
|
||||
* `UI.onRemove(options.step)` is emitted automatically and the module should not emit it.
|
||||
|
||||
### Name and description
|
||||
|
||||
For display in the web-based demo UI, set the `name` and `description` fields in the `info.json` file for the module.
|
||||
|
||||
## Info file
|
||||
|
||||
All module folders must have an `info.json` file which looks like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Name of Module to be displayed",
|
||||
"description": "Optional longer text explanation of the module's function",
|
||||
"url": "Optional link to module's source code or documentation",
|
||||
"inputs": {
|
||||
"var1": {
|
||||
"type": "text",
|
||||
"default": "default value"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Types may be one of "text", "integer", "float", "select".
|
||||
Integer and Float types should also specify minimum and maximum values like this:
|
||||
|
||||
```json
|
||||
"var1": {
|
||||
"type": "integer",
|
||||
"min": 0,
|
||||
"max": 4,
|
||||
"default": 1
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, "Select" type inputs should have a `values` array.
|
||||
|
||||
Also, A module may have output values. These must be defined as shown above.
|
||||
|
||||
### Progress reporting
|
||||
|
||||
The default "loading spinner" can be optionally overriden with a custom progress object to draw progress on the CLI, following is a basic module format for the same:
|
||||
|
||||
```js
|
||||
module.exports = function ModuleName(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Title of the Module";
|
||||
UI.onSetup(options.step);
|
||||
var output;
|
||||
|
||||
@@ -103,106 +208,7 @@ module.exports = function ModuleName(options,UI) {
|
||||
}
|
||||
```
|
||||
|
||||
### options
|
||||
|
||||
The object `options` stores some important information. This is how you can accept
|
||||
input from users. If you require a variable "x" from the user and the user passes
|
||||
it in, you will be able to access it as `options.x`.
|
||||
|
||||
Options also has some in-built properties. The `options.inBrowser` boolean denotes
|
||||
whether your module is being run on a browser.
|
||||
|
||||
### draw()
|
||||
|
||||
The draw method is run every time the step is `run` using `sequencer.run()`.
|
||||
So any calculations must go **into** the `draw()` method's definition.
|
||||
|
||||
What is not in the draw method, but is in the `module.exports` is executed only
|
||||
when the step is added. So whatever external npm modules are to be loaded, or
|
||||
constant definitions must be done **outside** the `draw()` method's definition.
|
||||
|
||||
`draw()` receives two arguments - `input` and `callback` :
|
||||
* `input` is an object which is essentially the output of the previous step.
|
||||
```js
|
||||
input = {
|
||||
src: "<$DataURL>",
|
||||
format: "<png|jpeg|gif>"
|
||||
}
|
||||
```
|
||||
* `callback` is a function which is responsible to tell the sequencer that the
|
||||
step has been "drawn".
|
||||
|
||||
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, call
|
||||
`callback()`, and set `options.step.output` equal to the output DataURL
|
||||
|
||||
* `progressObj` is an optional Object which handles the progress output of the step in the CLI, this is not consumed unless a custom progress bar needs to be drawn, for which this default spinner should be stopped with `progressObj.stop()` and image-sequencer is informed about the custom progress bar with `progressObj.overrideFlag = true;` following which this object can be overriden with custom progress object.
|
||||
|
||||
### UI Methods
|
||||
|
||||
The module is responsible for emitting various events for the UI to capture. There are
|
||||
four events in all:
|
||||
|
||||
* `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.
|
||||
* `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.onComplete(options.step)` 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.
|
||||
* `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:
|
||||
|
||||
* `module.draw()`
|
||||
|
||||
The `draw(input,callback)` method should accept an `input` parameter, which will be an object of the form:
|
||||
|
||||
```js
|
||||
input = {
|
||||
src: "datauri here",
|
||||
format: "jpeg/png/etc"
|
||||
}
|
||||
```
|
||||
|
||||
### options.title
|
||||
|
||||
For display in the web-based UI, each module may also have a title `options.title`.
|
||||
|
||||
## Info file
|
||||
|
||||
All module folders must have an `info.json` file which looks like the following:
|
||||
```json
|
||||
{
|
||||
"name": "Name of Module to be displayed",
|
||||
"description": "Optional longer text explanation of the module's function",
|
||||
"url": "Optional link to module's source code or documentation",
|
||||
"inputs": {
|
||||
"var1": {
|
||||
"type": "text",
|
||||
"default": "default value"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Types may be one of "text", "integer", "float", "select".
|
||||
Integer and Float types should also specify minimum and maximum values like this:
|
||||
|
||||
```json
|
||||
"var1": {
|
||||
"type": "integer",
|
||||
"min": 0,
|
||||
"max": 4,
|
||||
"default": 1
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, "Select" type inputs should have a `values` array.
|
||||
|
||||
Also, A module may have output values. These must be defined as shown above.
|
||||
The `progressObj` parameter of `draw()` is not consumed unless a custom progress bar needs to be drawn, for which this default spinner should be stopped with `progressObj.stop()` and image-sequencer is informed about the custom progress bar with `progressObj.overrideFlag = true;` following which this object can be overriden with custom progress object.
|
||||
|
||||
### Module example
|
||||
|
||||
|
||||
33022
dist/image-sequencer.js
vendored
33022
dist/image-sequencer.js
vendored
File diff suppressed because one or more lines are too long
2
dist/image-sequencer.min.js
vendored
2
dist/image-sequencer.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -40,61 +40,63 @@ window.onload = function() {
|
||||
</div>\
|
||||
<div class="col-md-8">\
|
||||
<div class="load" style="display:none;"><i class="fa fa-circle-o-notch fa-spin"></i></div>\
|
||||
<img alt="" class="img-thumbnail"/>\
|
||||
<a><img alt="" class=“img-thumbnail” /></a>\
|
||||
</div>\
|
||||
</div>\
|
||||
';
|
||||
|
||||
var tools =
|
||||
'<div class="tools btn-group">\
|
||||
<button confirm="Are you sure?" class="remove btn btn-xs btn-default">\
|
||||
<button confirm="Are you sure?" class="remove btn btn btn-default">\
|
||||
<i class="fa fa-trash"></i>\
|
||||
</button>\
|
||||
</div>';
|
||||
|
||||
step.ui = parser.parseFromString(step.ui,'text/html');
|
||||
step.ui = step.ui.querySelector('div.row');
|
||||
step.imgElement = step.ui.querySelector('img');
|
||||
step.linkElement = step.ui.querySelector('a');
|
||||
step.imgElement = step.ui.querySelector('a img');
|
||||
|
||||
if(sequencer.modulesInfo().hasOwnProperty(step.name)) {
|
||||
var inputs = sequencer.modulesInfo(step.name).inputs;
|
||||
var outputs = sequencer.modulesInfo(step.name).outputs;
|
||||
var io = Object.assign(inputs, outputs);
|
||||
for (var i in io) {
|
||||
var isInput = inputs.hasOwnProperty(i);
|
||||
var ioUI = "";
|
||||
var inputDesc = (isInput)?inputs[i]:{};
|
||||
var merged = Object.assign(inputs, outputs); // combine outputs w inputs
|
||||
for (var paramName in merged) {
|
||||
var isInput = inputs.hasOwnProperty(paramName);
|
||||
var html = "";
|
||||
var inputDesc = (isInput)?inputs[paramName]:{};
|
||||
if (!isInput) {
|
||||
ioUI += "<span class=\"output\"></span>";
|
||||
}
|
||||
else if (inputDesc.type.toLowerCase() == "select") {
|
||||
ioUI += "<select class=\"form-control\" name=\""+i+"\">";
|
||||
html += "<span class=\"output\"></span>";
|
||||
} else if (inputDesc.type.toLowerCase() == "select") {
|
||||
html += "<select class=\"form-control\" name=\""+paramName+"\">";
|
||||
for (var option in inputDesc.values) {
|
||||
ioUI += "<option>"+inputDesc.values[option]+"</option>";
|
||||
html += "<option>"+inputDesc.values[option]+"</option>";
|
||||
}
|
||||
ioUI += "</select>";
|
||||
}
|
||||
else {
|
||||
ioUI = "<input class=\"form-control\" type=\""+inputDesc.type+"\" name=\""+i+"\">";
|
||||
html += "</select>";
|
||||
} else {
|
||||
html = "<input class=\"form-control\" type=\""+inputDesc.type+"\" name=\""+paramName+"\">";
|
||||
}
|
||||
var div = document.createElement('div');
|
||||
div.className = "row";
|
||||
div.setAttribute('name', i);
|
||||
div.setAttribute('name', paramName);
|
||||
var description = inputs[paramName].desc || paramName;
|
||||
div.innerHTML = "<div class='det'>\
|
||||
<label for='" + i + "'>" + i + "</label>\
|
||||
"+ioUI+"\
|
||||
<label for='" + paramName + "'>" + description + "</label>\
|
||||
"+html+"\
|
||||
</div>";
|
||||
step.ui.querySelector('div.details').appendChild(div);
|
||||
}
|
||||
$(step.ui.querySelector('div.details')).append("<p><button class='btn btn-default btn-save'>Save</button></p>");
|
||||
|
||||
// on clicking Save in the details pane of the step
|
||||
$(step.ui.querySelector('div.details .btn-save')).click(function saveOptions() {
|
||||
function saveOptions() {
|
||||
$(step.ui.querySelector('div.details')).find('input,select').each(function(i, input) {
|
||||
step.options[$(input).attr('name')] = input.value;
|
||||
});
|
||||
sequencer.run();
|
||||
});
|
||||
}
|
||||
|
||||
// on clicking Save in the details pane of the step
|
||||
$(step.ui.querySelector('div.details .btn-save')).click(saveOptions);
|
||||
}
|
||||
|
||||
if(step.name != "load-image")
|
||||
@@ -116,11 +118,20 @@ window.onload = function() {
|
||||
$(step.ui.querySelector('img')).show();
|
||||
|
||||
step.imgElement.src = step.output;
|
||||
step.linkElement.href = step.output;
|
||||
|
||||
function fileExtension(output) {
|
||||
return output.split('/')[1].split(';')[0];
|
||||
}
|
||||
|
||||
step.linkElement.download = step.name + "." + fileExtension(step.output);
|
||||
step.linkElement.target = "_blank";
|
||||
|
||||
if(sequencer.modulesInfo().hasOwnProperty(step.name)) {
|
||||
var inputs = sequencer.modulesInfo(step.name).inputs;
|
||||
var outputs = sequencer.modulesInfo(step.name).outputs;
|
||||
for (var i in inputs) {
|
||||
if (step.options[i] !== undefined &&
|
||||
if (step.options[i] !== undefined &&
|
||||
inputs[i].type.toLowerCase() === "input") step.ui.querySelector('div[name="' + i + '"] input')
|
||||
.value = step.options[i];
|
||||
if (step.options[i] !== undefined &&
|
||||
@@ -155,41 +166,13 @@ window.onload = function() {
|
||||
|
||||
});
|
||||
|
||||
|
||||
// File handling
|
||||
|
||||
$('#addStep select').on('change', selectNewStepUI);
|
||||
|
||||
function selectNewStepUI() {
|
||||
$('#options').html('');
|
||||
var m = $('#addStep select').val();
|
||||
for(var input in modulesInfo[m].inputs) {
|
||||
var inputUI = "";
|
||||
var inputDesc = modulesInfo[m].inputs[input];
|
||||
if (inputDesc.type.toLowerCase() == "select") {
|
||||
inputUI += "<select class=\"form-control\" name=\""+input+"\">";
|
||||
for (var option in inputDesc.values) {
|
||||
inputUI += "<option>"+inputDesc.values[option]+"</option>";
|
||||
}
|
||||
inputUI += "</select>";
|
||||
}
|
||||
else {
|
||||
inputUI = "<input class=\"form-control\" type=\""+inputDesc.type+"\" name=\""+input+"\">";
|
||||
}
|
||||
$('#options').append(
|
||||
'<div class="row">\
|
||||
<div class="col-md-5 labels">\
|
||||
'+input+':\
|
||||
</div>\
|
||||
<div class="col-md-5">\
|
||||
'+inputUI+'\
|
||||
</div>\
|
||||
</div>'
|
||||
);
|
||||
}
|
||||
$('#addStep .info').html(sequencer.modulesInfo(m).description);
|
||||
}
|
||||
|
||||
|
||||
function addStepUI() {
|
||||
var options = {};
|
||||
var inputs = $('#options input, #options select');
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
|
||||
<script src="../dist/image-sequencer.js"></script>
|
||||
</head>
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 663 KiB After Width: | Height: | Size: 489 KiB |
@@ -7,6 +7,8 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF8">
|
||||
<link rel="icon" sizes="192x192" href="../icons/ic_192.png">
|
||||
|
||||
|
||||
<title>Image Sequencer</title>
|
||||
|
||||
@@ -46,18 +48,20 @@
|
||||
|
||||
<section id="steps" class="row"></section>
|
||||
|
||||
<section id="addStep">
|
||||
<div class="row">
|
||||
<select class="form-control">
|
||||
<option value="none" disabled selected>Select a new step...</option>
|
||||
</select>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div id="options"></div>
|
||||
</div>
|
||||
<div class="row add">
|
||||
<button class="btn btn-success btn-lg" name="add">Add Step</button>
|
||||
<hr />
|
||||
|
||||
<section id="addStep" class="panel panel-primary">
|
||||
<div class="form-inline">
|
||||
<div class="panel-body">
|
||||
<div style="text-align:center;">
|
||||
<select class="form-control input-lg">
|
||||
<option value="none" disabled selected>Select a new step...</option>
|
||||
</select>
|
||||
<button class="btn btn-success btn-lg" name="add">Add Step</button>
|
||||
</div>
|
||||
<br />
|
||||
<p class="info" style="padding:8px;">Select a new module to add to your sequence.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -66,7 +70,6 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
var sequencer;
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
BIN
icons/ic_144.png
Executable file
BIN
icons/ic_144.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
BIN
icons/ic_192.png
Executable file
BIN
icons/ic_192.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
icons/ic_96.png
Executable file
BIN
icons/ic_96.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "image-sequencer",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.3",
|
||||
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
|
||||
"main": "src/ImageSequencer.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
// add steps to the sequencer
|
||||
function AddStep(ref, image, name, o) {
|
||||
|
||||
function addStep(image, name, o_) {
|
||||
var moduleInfo = ref.modules[name][1];
|
||||
|
||||
var o = ref.copy(o_);
|
||||
o.number = ref.options.sequencerCounter++; //Gives a Unique ID to each step
|
||||
o.name = o_.name || name;
|
||||
o.number = ref.options.sequencerCounter++; // gives a unique ID to each step
|
||||
o.name = o_.name || name || moduleInfo.name;
|
||||
o.description = o_.description || moduleInfo.description;
|
||||
o.selector = o_.selector || 'ismod-' + name;
|
||||
o.container = o_.container || ref.options.selector;
|
||||
o.image = image;
|
||||
@@ -11,6 +15,7 @@ function AddStep(ref, image, name, o) {
|
||||
|
||||
o.step = {
|
||||
name: o.name,
|
||||
description: o.description,
|
||||
ID: o.number,
|
||||
imageName: o.image,
|
||||
inBrowser: ref.options.inBrowser,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
if (typeof window !== 'undefined') {window.$ = window.jQuery = require('jquery'); isBrowser = true}
|
||||
if (typeof window !== 'undefined') {isBrowser = true}
|
||||
else {var isBrowser = false}
|
||||
|
||||
ImageSequencer = function ImageSequencer(options) {
|
||||
|
||||
options = options || {};
|
||||
options.inBrowser = options.inBrowser || isBrowser;
|
||||
// if (options.inBrowser) options.ui = options.ui || require('./UserInterface');
|
||||
options.sequencerCounter = 0;
|
||||
|
||||
function objTypeOf(object){
|
||||
@@ -42,7 +41,7 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
formatInput = require('./FormatInput'),
|
||||
images = {},
|
||||
inputlog = [],
|
||||
events = require('./UserInterface')(),
|
||||
events = require('./ui/UserInterface')(),
|
||||
fs = require('fs');
|
||||
|
||||
// if in browser, prompt for an image
|
||||
@@ -145,7 +144,6 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
|
||||
inputlog.push({method:"loadImages", json_q:copy(json_q)});
|
||||
var loadedimages = this.copy(json_q.loadedimages);
|
||||
// require('./LoadImage')(this,i,json_q.images[i]);
|
||||
|
||||
var ret = {
|
||||
name: "ImageSequencer Wrapper",
|
||||
@@ -165,7 +163,7 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
return;
|
||||
}
|
||||
var img = loadedimages[i];
|
||||
require('./LoadImage')(sequencer,img,json_q.images[img],function(){
|
||||
require('./ui/LoadImage')(sequencer,img,json_q.images[img],function(){
|
||||
load(++i);
|
||||
});
|
||||
}
|
||||
@@ -180,7 +178,7 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
}
|
||||
|
||||
function setUI(UI) {
|
||||
this.events = require('./UserInterface')(UI);
|
||||
this.events = require('./ui/UserInterface')(UI);
|
||||
}
|
||||
|
||||
var exportBin = function(dir,basic) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// insert one or more steps at a given index in the sequencer
|
||||
function InsertStep(ref, image, index, name, o) {
|
||||
|
||||
function insertStep(image, index, name, o_) {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* Core modules and their info files
|
||||
*/
|
||||
module.exports = {
|
||||
'green-channel': [
|
||||
require('./modules/GreenChannel/Module'),require('./modules/GreenChannel/info')
|
||||
'channel': [
|
||||
require('./modules/Channel/Module'),require('./modules/Channel/info')
|
||||
],
|
||||
'brightness': [
|
||||
require('./modules/Brightness/Module'),require('./modules/Brightness/info')
|
||||
@@ -11,8 +11,8 @@ module.exports = {
|
||||
'edge-detect':[
|
||||
require('./modules/EdgeDetect/Module'),require('./modules/EdgeDetect/info')
|
||||
],
|
||||
'ndvi-red': [
|
||||
require('./modules/NdviRed/Module'),require('./modules/NdviRed/info')
|
||||
'ndvi': [
|
||||
require('./modules/Ndvi/Module'),require('./modules/Ndvi/info')
|
||||
],
|
||||
'invert': [
|
||||
require('./modules/Invert/Module'),require('./modules/Invert/info')
|
||||
@@ -20,8 +20,8 @@ module.exports = {
|
||||
'crop': [
|
||||
require('./modules/Crop/Module'),require('./modules/Crop/info')
|
||||
],
|
||||
'segmented-colormap': [
|
||||
require('./modules/SegmentedColormap/Module'),require('./modules/SegmentedColormap/info')
|
||||
'colormap': [
|
||||
require('./modules/Colormap/Module'),require('./modules/Colormap/info')
|
||||
],
|
||||
'decode-qr': [
|
||||
require('./modules/DecodeQr/Module'),require('./modules/DecodeQr/info')
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// Uses a given image as input and replaces it with the output.
|
||||
// Works only in the browser.
|
||||
function ReplaceImage(ref,selector,steps,options) {
|
||||
if(!ref.options.inBrowser) return false; // This isn't for Node.js
|
||||
var tempSequencer = ImageSequencer({ui: false});
|
||||
var this_ = ref;
|
||||
var input = document.querySelectorAll(selector);
|
||||
if (window.hasOwnProperty('$')) var input = $(selector);
|
||||
else var input = document.querySelectorAll(selector);
|
||||
var images = [];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if (input[i] instanceof HTMLImageElement) images.push(input[i]);
|
||||
@@ -10,7 +13,8 @@ function ReplaceImage(ref,selector,steps,options) {
|
||||
|
||||
function replaceImage (img, steps) {
|
||||
var url = img.src;
|
||||
var ext = url.split('.').pop();
|
||||
// refactor to filetypeFromUrl()
|
||||
var ext = url.split('?')[0].split('.').pop();
|
||||
|
||||
var xmlHTTP = new XMLHttpRequest();
|
||||
xmlHTTP.open('GET', url, true);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
module.exports = function Blur(options,UI){
|
||||
options = options || {};
|
||||
options.title = "Blur";
|
||||
options.description = "Blur an Image";
|
||||
options.blur = options.blur || 2
|
||||
|
||||
//Tell the UI that a step has been set up
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "blur",
|
||||
"description": "Blur an image by a given value",
|
||||
"name": "Blur",
|
||||
"description": "Gaussian blur an image by a given value, typically 0-5",
|
||||
"inputs": {
|
||||
"blur": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
module.exports = function Brightness(options,UI){
|
||||
options = options || {};
|
||||
options.title = "Brightness";
|
||||
options.description = "Changes the brightness of the image";
|
||||
|
||||
//Tell the UI that a step has been set up
|
||||
UI.onSetup(options.step);
|
||||
@@ -64,4 +62,4 @@ module.exports = function Brightness(options,UI){
|
||||
output: output,
|
||||
UI: UI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Brightness",
|
||||
"description": "Change the brightness of the image by given value",
|
||||
"description": "Change the brightness of the image by given percent value",
|
||||
"inputs": {
|
||||
"brightness": {
|
||||
"type": "integer",
|
||||
@@ -8,4 +8,4 @@
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
* Display only the green channel
|
||||
* Display only one color channel
|
||||
*/
|
||||
module.exports = function GreenChannel(options,UI) {
|
||||
module.exports = function Channel(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Green channel only";
|
||||
options.description = "Displays only the green channel of an image";
|
||||
options.channel = options.channel || "green";
|
||||
|
||||
// Tell UI that a step has been set up
|
||||
UI.onSetup(options.step);
|
||||
@@ -21,7 +20,9 @@ module.exports = function GreenChannel(options,UI) {
|
||||
var step = this;
|
||||
|
||||
function changePixel(r, g, b, a) {
|
||||
return [0, g, 0, a];
|
||||
if (options.channel == "red") return [r, 0, 0, a];
|
||||
if (options.channel == "green") return [0, g, 0, a];
|
||||
if (options.channel == "blue") return [0, 0, b, a];
|
||||
}
|
||||
|
||||
function output(image,datauri,mimetype){
|
||||
12
src/modules/Channel/info.json
Normal file
12
src/modules/Channel/info.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "Channel",
|
||||
"description": "Displays only one color channel of an image -- default is green",
|
||||
"inputs": {
|
||||
"channel": {
|
||||
"type": "select",
|
||||
"desc": "Color channel",
|
||||
"default": "green",
|
||||
"values": ["red", "green", "blue"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,11 @@
|
||||
* Adapted from bgamari's work in Infragram: https://github.com/p-v-o-s/infragram-js/commit/346c97576a07b71a55671d17e0153b7df74e803b
|
||||
*/
|
||||
|
||||
module.exports = function SegmentedColormap(value, options) {
|
||||
module.exports = function Colormap(value, options) {
|
||||
options.colormap = options.colormap || colormaps.default;
|
||||
// if a lookup table is provided as an array:
|
||||
if(typeof(options.colormap) == "object")
|
||||
colormapFunction = segmented_colormap(options.colormap);
|
||||
colormapFunction = colormap(options.colormap);
|
||||
// if a stored colormap is named with a string like "fastie":
|
||||
else if(colormaps.hasOwnProperty(options.colormap))
|
||||
colormapFunction = colormaps[options.colormap];
|
||||
@@ -23,7 +23,7 @@ module.exports = function SegmentedColormap(value, options) {
|
||||
return colormapFunction(value / 255.00);
|
||||
}
|
||||
|
||||
function segmented_colormap(segments) {
|
||||
function colormap(segments) {
|
||||
return function(x) {
|
||||
var i, result, x0, x1, xstart, y0, y1, _i, _j, _len, _ref, _ref1, _ref2, _ref3;
|
||||
_ref = [0, 0], y0 = _ref[0], y1 = _ref[1];
|
||||
@@ -52,29 +52,29 @@ function segmented_colormap(segments) {
|
||||
};
|
||||
|
||||
var colormaps = {
|
||||
greyscale: segmented_colormap([
|
||||
greyscale: colormap([
|
||||
[0, [0, 0, 0], [255, 255, 255] ],
|
||||
[1, [255, 255, 255], [255, 255, 255] ]
|
||||
]),
|
||||
default: segmented_colormap([
|
||||
default: colormap([
|
||||
[0, [0, 0, 255], [0, 255, 0] ],
|
||||
[0.25, [0, 255, 0], [255, 255, 0] ],
|
||||
[0.50, [0, 255, 255], [255, 255, 0] ],
|
||||
[0.75, [255, 255, 0], [255, 0, 0] ]
|
||||
]),
|
||||
ndvi: segmented_colormap([
|
||||
ndvi: colormap([
|
||||
[0, [0, 0, 255], [38, 195, 195] ],
|
||||
[0.5, [0, 150, 0], [255, 255, 0] ],
|
||||
[0.75, [255, 255, 0], [255, 50, 50] ]
|
||||
]),
|
||||
stretched: segmented_colormap([
|
||||
stretched: colormap([
|
||||
[0, [0, 0, 255], [0, 0, 255] ],
|
||||
[0.1, [0, 0, 255], [38, 195, 195] ],
|
||||
[0.5, [0, 150, 0], [255, 255, 0] ],
|
||||
[0.7, [255, 255, 0], [255, 50, 50] ],
|
||||
[0.9, [255, 50, 50], [255, 50, 50] ]
|
||||
]),
|
||||
fastie: segmented_colormap([
|
||||
fastie: colormap([
|
||||
[0, [255, 255, 255], [0, 0, 0] ],
|
||||
[0.167, [0, 0, 0], [255, 255, 255] ],
|
||||
[0.33, [255, 255, 255], [0, 0, 0] ],
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = function SegmentedColormap(options,UI) {
|
||||
module.exports = function Colormap(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Segmented Colormap";
|
||||
|
||||
// Tell the UI that a step has been set up.
|
||||
UI.onSetup(options.step);
|
||||
@@ -19,7 +18,7 @@ module.exports = function SegmentedColormap(options,UI) {
|
||||
|
||||
function changePixel(r, g, b, a) {
|
||||
var combined = (r + g + b) / 3.000;
|
||||
var res = require('./SegmentedColormap')(combined, options);
|
||||
var res = require('./Colormap')(combined, options);
|
||||
return [res[0], res[1], res[2], 255];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Segmented Colormap",
|
||||
"description": "Maps brightness values (average of red, green & blue) to a given color lookup table, made up of a set of one more color gradients.",
|
||||
"name": "Colormap",
|
||||
"description": "Maps brightness values (average of red, green & blue) to a given color lookup table, made up of a set of one more color gradients.\n\nFor example, 'cooler' colors like blue could represent low values, while 'hot' colors like red could represent high values.",
|
||||
"inputs": {
|
||||
"colormap": {
|
||||
"type": "select",
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
module.exports = function CropModule(options,UI) {
|
||||
|
||||
// TODO: we could also set this to {} if nil in AddModule.js to avoid this line:
|
||||
options = options || {};
|
||||
options.title = "Crop Image";
|
||||
|
||||
// Tell the UI that a step has been added
|
||||
UI.onSetup(options.step);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Crop",
|
||||
"description": "Crop image to given x, y, w, h",
|
||||
"description": "Crop image to given x, y, w, h in pixels, measured from top left",
|
||||
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
|
||||
"inputs": {
|
||||
"x": {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
module.exports = function DoNothing(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Decode QR Code";
|
||||
|
||||
// Tell the UI that a step has been added
|
||||
UI.onSetup(options.step);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "Decode QR",
|
||||
"description": "Search for and decode a QR code in the image",
|
||||
"inputs": {
|
||||
},
|
||||
"outputs": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = function Dynamic(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Dynamic";
|
||||
|
||||
// Tell the UI that a step has been set up.
|
||||
UI.onSetup(options.step);
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
module.exports = function edgeDetect(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Detect Edges";
|
||||
options.description = "Detects the edges in an image";
|
||||
options.blur = options.blur || 2
|
||||
options.highThresholdRatio = options.highThresholdRatio||0.2
|
||||
options.lowThresholdRatio = options.lowThresholdRatio||0.15
|
||||
@@ -66,4 +64,4 @@ module.exports = function edgeDetect(options,UI) {
|
||||
output: output,
|
||||
UI: UI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
"default": 0.15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
module.exports = function DoNothing(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Fisheye GL";
|
||||
|
||||
var output;
|
||||
|
||||
// Tell the UI that a step has been set up.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"name": "Fisheye GL",
|
||||
"description": "Correct fisheye, or barrel distortion, in images (with WebGL -- adapted from fisheye-correction-webgl by @bluemir).",
|
||||
"requires": [ "webgl" ],
|
||||
"inputs": {
|
||||
"a": {
|
||||
"type": "float",
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "Green Channel",
|
||||
"inputs": {
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,6 @@
|
||||
module.exports = function Invert(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Invert Colors";
|
||||
options.description = "Inverts the colors of the image";
|
||||
|
||||
// Tell UI that a step has been set up.
|
||||
UI.onSetup(options.step);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* NDVI with red filter (blue channel is infrared)
|
||||
*/
|
||||
module.exports = function NdviRed(options,UI) {
|
||||
module.exports = function Ndvi(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "NDVI for red-filtered cameras (blue is infrared)";
|
||||
options.filter = options.filter || "red";
|
||||
|
||||
// Tell the UI that a step has been set up.
|
||||
UI.onSetup(options.step);
|
||||
@@ -21,7 +21,8 @@ module.exports = function NdviRed(options,UI) {
|
||||
var step = this;
|
||||
|
||||
function changePixel(r, g, b, a) {
|
||||
var ndvi = (b - r) / (1.00 * b + r);
|
||||
if (options.filter == "red") var ndvi = (b - r) / (1.00 * b + r);
|
||||
if (options.filter == "blue") var ndvi = (r - b) / (1.00 * b + r);
|
||||
var x = 255 * (ndvi + 1) / 2;
|
||||
return [x, x, x, a];
|
||||
}
|
||||
12
src/modules/Ndvi/info.json
Normal file
12
src/modules/Ndvi/info.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "NDVI",
|
||||
"description": "Normalized Difference Vegetation Index, or NDVI, is an image analysis technique used with aerial photography. It's a way to visualize the amounts of infrared and other wavelengths of light reflected from vegetation by comparing ratios of blue and red light absorbed versus green and IR light reflected. NDVI is used to evaluate the health of vegetation in satellite imagery, where it correlates with how much photosynthesis is happening. This is helpful in assessing vegetative health or stress. <a href='https://publiclab.org/ndvi'>Read more</a>.<br /><br/>This is designed for use with red-filtered single camera <a href='http://publiclab.org/infragram'>DIY Infragram cameras</a>; change to 'blue' for blue filters",
|
||||
"inputs": {
|
||||
"filter": {
|
||||
"type": "select",
|
||||
"desc": "Filter color",
|
||||
"default": "red",
|
||||
"values": ["red", "blue"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "NDVI for red filters",
|
||||
"description": "Normalized Difference Vegetation Index, or NDVI, is an image analysis technique used with aerial photography. It's a way to visualize the amounts of infrared and other wavelengths of light reflected from vegetation. Because both these methods compare ratios of blue and red light absorbed versus green and IR light reflected, they can be used to evaluate the health of vegetation. It's a snapshot of how much photosynthesis is happening. This is helpful in assessing vegetative health or stress. <a href='https://publiclab.org/ndvi'>Read more</a>.<br /><br/>This is designed for use with red-filtered single camera <a href='http://publiclab.org/infragram'>DIY Infragram cameras</a>.",
|
||||
"inputs": {
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
/*
|
||||
* Saturate an image
|
||||
* Saturate an image with a value from 0 to 1
|
||||
*/
|
||||
module.exports = function Saturation(options,UI) {
|
||||
|
||||
options = options || {};
|
||||
options.title = "Saturation";
|
||||
options.description = "Saturate an image";
|
||||
|
||||
// Tell UI that a step has been set up
|
||||
UI.onSetup(options.step);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "Saturation",
|
||||
"description": "Change the saturation of the image by given value",
|
||||
"description": "Change the saturation of the image by given value, from 0-1, with 1 being 100% saturated.",
|
||||
"inputs": {
|
||||
"saturation": {
|
||||
"type": "integer",
|
||||
"desc": "saturation for the new image between 0 and 2, 0 being black and white and 2 being fully saturated",
|
||||
"desc": "saturation for the new image between 0 and 2, 0 being black and white and 2 being highly saturated",
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
module.exports = function ImageThreshold(options) {
|
||||
options = options || {};
|
||||
options.title = "Threshold image";
|
||||
options.threshold = options.threshold || 30;
|
||||
|
||||
var image;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Threshold image",
|
||||
"description": "...",
|
||||
"inputs": {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ module.exports = function PixelManipulation(image, options) {
|
||||
getPixels(image.src, function(err, pixels) {
|
||||
|
||||
if(err) {
|
||||
console.log('Bad image path');
|
||||
console.log('Bad image path', image);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ function LoadImage(ref, name, src, main_callback) {
|
||||
function loadImage(name, src) {
|
||||
var step = {
|
||||
name: "load-image",
|
||||
description: "This initial step loads and displays the original image without any modifications.",
|
||||
description: "This initial step loads and displays the original image without any modifications.<br /><br />To work with a new or different image, drag one into the drop zone.",
|
||||
ID: ref.options.sequencerCounter++,
|
||||
imageName: name,
|
||||
inBrowser: ref.options.inBrowser,
|
||||
@@ -41,10 +41,10 @@ test('addSteps is two-way chainable.', function (t){
|
||||
});
|
||||
|
||||
test('addSteps is two-way chainable without loadImages.', function (t){
|
||||
var returnval = sequencer.addSteps("image3","ndvi-red");
|
||||
var returnval = sequencer.addSteps("image3","ndvi");
|
||||
t.equal(returnval.name,"ImageSequencer","Sequencer is returned");
|
||||
t.equal(sequencer.images.image3.steps.length,3,"Step length increased");
|
||||
t.equal(sequencer.images.image3.steps[2].options.name,"ndvi-red","Correct Step Added");
|
||||
t.equal(sequencer.images.image3.steps[2].options.name,"ndvi","Correct Step Added");
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -79,9 +79,9 @@ test('insertSteps is two-way chainable.', function (t){
|
||||
});
|
||||
|
||||
test('insertSteps is two-way chainable without loadImages.', function (t){
|
||||
var returnval = sequencer.insertSteps("image5",1,"ndvi-red");
|
||||
var returnval = sequencer.insertSteps("image5",1,"ndvi");
|
||||
t.equal(returnval.name,"ImageSequencer","Sequencer is returned");
|
||||
t.equal(sequencer.images.image5.steps.length,3);
|
||||
t.equal(sequencer.images.image5.steps[1].options.name,"ndvi-red","Correct Step Inserrted");
|
||||
t.equal(sequencer.images.image5.steps[1].options.name,"ndvi","Correct Step Inserrted");
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -82,38 +82,39 @@ test('loadImage works too.', function (t){
|
||||
});
|
||||
|
||||
test('addSteps("image","name") adds a step', function (t) {
|
||||
sequencer.addSteps('test','green-channel');
|
||||
sequencer.addSteps('test','channel');
|
||||
t.equal(sequencer.images.test.steps.length, 2, "Length of steps increased")
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "green-channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[1].options.description, "Displays only one color channel of an image -- default is green", "Step description shown");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('addSteps("name") adds a step', function (t) {
|
||||
sequencer.addSteps('green-channel');
|
||||
sequencer.addSteps('channel');
|
||||
t.equal(sequencer.images.test.steps.length, 3, "Length of steps increased");
|
||||
t.equal(sequencer.images.test.steps[2].options.name, "green-channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[2].options.name, "channel", "Correct Step Added");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('addSteps(["name"]) adds a step', function (t) {
|
||||
sequencer.addSteps(['green-channel','invert']);
|
||||
sequencer.addSteps(['channel','invert']);
|
||||
t.equal(sequencer.images.test.steps.length, 5, "Length of steps increased by two")
|
||||
t.equal(sequencer.images.test.steps[3].options.name, "green-channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[3].options.name, "channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[4].options.name, "invert", "Correct Step Added");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('addSteps("name",o) adds a step', function (t) {
|
||||
sequencer.addSteps('green-channel',{});
|
||||
sequencer.addSteps('channel',{});
|
||||
t.equal(sequencer.images.test.steps.length, 6, "Length of steps increased");
|
||||
t.equal(sequencer.images.test.steps[5].options.name, "green-channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[5].options.name, "channel", "Correct Step Added");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('addSteps("image","name",o) adds a step', function (t) {
|
||||
sequencer.addSteps('test','green-channel',{});
|
||||
sequencer.addSteps('test','channel',{});
|
||||
t.equal(sequencer.images.test.steps.length, 7, "Length of steps increased");
|
||||
t.equal(sequencer.images.test.steps[6].options.name, "green-channel", "Correct Step Added");
|
||||
t.equal(sequencer.images.test.steps[6].options.name, "channel", "Correct Step Added");
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -136,30 +137,30 @@ test('removeSteps(position) removes steps', function (t) {
|
||||
});
|
||||
|
||||
test('insertSteps("image",position,"module",options) inserts a step', function (t) {
|
||||
sequencer.insertSteps('test',1,'green-channel',{});
|
||||
sequencer.insertSteps('test',1,'channel',{});
|
||||
t.equal(sequencer.images.test.steps.length, 3, "Length of Steps increased");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "green-channel", "Correct Step Inserted");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "channel", "Correct Step Inserted");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('insertSteps("image",position,"module") inserts a step', function (t) {
|
||||
sequencer.insertSteps('test',1,'green-channel');
|
||||
sequencer.insertSteps('test',1,'channel');
|
||||
t.equal(sequencer.images.test.steps.length, 4, "Length of Steps increased");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "green-channel", "Correct Step Inserted");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "channel", "Correct Step Inserted");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('insertSteps(position,"module") inserts a step', function (t) {
|
||||
sequencer.insertSteps(1,'green-channel');
|
||||
sequencer.insertSteps(1,'channel');
|
||||
t.equal(sequencer.images.test.steps.length, 5, "Length of Steps increased");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "green-channel", "Correct Step Inserted");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "channel", "Correct Step Inserted");
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('insertSteps({image: {index: index, name: "module", o: options} }) inserts a step', function (t) {
|
||||
sequencer.insertSteps({test: {index:1, name:'green-channel', o:{} } });
|
||||
sequencer.insertSteps({test: {index:1, name:'channel', o:{} } });
|
||||
t.equal(sequencer.images.test.steps.length, 6, "Length of Steps increased");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "green-channel", "Correct Step Inserted");
|
||||
t.equal(sequencer.images.test.steps[1].options.name, "channel", "Correct Step Inserted");
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user