Compare commits

..

5 Commits

Author SHA1 Message Date
Varun Gupta
d887f5eb61 Update version (#208)
* 1.1.0

* 1.2.0

* check in dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-04-09 16:53:40 -04:00
Varun Gupta
3b791ad58b add loading spinner fallback (#202)
* add loading spinner fallback fixes #189

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* handle testing with progress spinners

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* apply fixes and improvements

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add example

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* bug fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* resolves #189

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-03-31 01:21:28 -04:00
Varun Gupta
fba80bb151 Dynamic fix as fun (#207)
getNeighborPixel(x, y) method for Dynamic module
2018-03-30 17:41:30 -04:00
Varun Gupta
0ceb36ffde 1.1.0 (#206) 2018-03-24 10:06:50 -04:00
Jeffrey Warren
edaa8895c7 Update info.json with NDVI description (#199)
* Update info.json

* compiled
2018-03-12 13:13:43 -04:00
20 changed files with 11941 additions and 10998 deletions

View File

@@ -31,17 +31,64 @@ 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);
var output = /*do something with the input*/ ;
var output = function(input){
/* do something with the input */
return input;
}
this.output = output;
this.output = output(input);
options.step.output = output.src;
callback();
UI.onComplete(options.step);
}
return {
options: options,
draw: draw,
output: output,
UI: 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
```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,progressObj) {
/* If you wish to supply your own progress bar you need to override progressObj */
progressObj.stop() // Stop the current progress spinner
progressObj.overrideFlag = true; // Tell image sequencer that you will supply your own progressBar
/* Override the object and give your own progress Bar */
progressObj = /* Your own progress Object */
UI.onDraw(options.step);
var output = function(input){
/* do something with the input */
return input;
};
this.output = output();
options.step.output = output.src;
callback();
UI.onComplete(options.step);
@@ -89,6 +136,8 @@ When you have done your calculations and produced an image output, you are requi
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

21142
dist/image-sequencer.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,7 @@
require('./src/ImageSequencer');
sequencer = ImageSequencer({ui: false});
var Spinner = require('ora')
var program = require('commander');
var readlineSync = require('readline-sync');
@@ -109,12 +110,19 @@ sequencer.loadImages(program.image,function(){
sequencer.addSteps(step, options);
});
var spinnerObj = Spinner('Your Image is being processed..').start();
// Run the sequencer.
sequencer.run(function(){
sequencer.run(spinnerObj,function(){
// Export all images or final image as binary files.
sequencer.exportBin(program.output,program.basic);
//check if spinner was not overriden stop it
if(!spinnerObj.overrideFlag) {
spinnerObj.succeed()
console.log(`\nDone!!`)
}
});

View File

@@ -1,6 +1,6 @@
{
"name": "image-sequencer",
"version": "1.0.0",
"version": "1.2.0",
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
"main": "src/ImageSequencer.js",
"scripts": {
@@ -32,6 +32,7 @@
"jsqr": "^0.2.2",
"lodash": "^4.17.5",
"ndarray-gaussian-filter": "^1.0.0",
"ora": "^2.0.0",
"pace": "0.0.4",
"readline-sync": "^1.4.7",
"save-pixels": "~2.3.4",

View File

@@ -114,7 +114,13 @@ ImageSequencer = function ImageSequencer(options) {
return this;
}
function run(t_image,t_from) {
function run(spinnerObj,t_image,t_from) {
let progressObj;
if(arguments[0] != 'test'){
progressObj = spinnerObj
delete arguments['0']
}
var this_ = (this.name == "ImageSequencer")?this:this.sequencer;
var args = (this.name == "ImageSequencer")?[]:[this.images];
for (var arg in arguments) args.push(copy(arguments[arg]));
@@ -126,7 +132,7 @@ ImageSequencer = function ImageSequencer(options) {
var json_q = formatInput.call(this_,args,"r");
require('./Run')(this_, json_q, callback);
require('./Run')(this_, json_q, callback,progressObj);
return true;
}

View File

@@ -28,7 +28,7 @@ function ReplaceImage(ref,selector,steps,options) {
function make(url) {
tempSequencer.loadImage(url, function(){
this.addSteps(steps).run(function(out){
this.addSteps(steps).run({stop:function(){}},function(out){
img.src = out;
});
});

View File

@@ -1,4 +1,5 @@
function Run(ref, json_q, callback) {
function Run(ref, json_q, callback,progressObj) {
if(!progressObj) progressObj = {stop: function(){}}
function drawStep(drawarray, pos) {
if (pos == drawarray.length && drawarray[pos - 1] !== undefined) {
@@ -17,7 +18,7 @@ function Run(ref, json_q, callback) {
var input = ref.images[image].steps[i - 1].output;
ref.images[image].steps[i].draw(ref.copy(input), function onEachStep() {
drawStep(drawarray, ++pos);
});
},progressObj);
}
}

View File

@@ -11,7 +11,10 @@ module.exports = function Blur(options,UI){
UI.onSetup(options.step);
var output;
function draw(input,callback){
function draw(input,callback,progressObj){
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -11,7 +11,16 @@ module.exports = function Brightness(options,UI){
UI.onSetup(options.step);
var output;
function draw(input,callback){
function draw(input,callback,progressObj){
progressObj.stop(true);
progressObj.overrideFlag = true;
/*
In this case progress is handled by changepixel internally otherwise progressObj
needs to be overriden and used
For eg. progressObj = new SomeProgressModule()
*/
// Tell the UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -8,7 +8,10 @@ module.exports = function Dynamic(options,UI) {
var output;
// This function is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that the step is being drawn
UI.onDraw(options.step);
@@ -35,6 +38,10 @@ module.exports = function Dynamic(options,UI) {
});
function changePixel(r, g, b, a) {
/* neighbourpixels can be calculated by
this.getNeighbourPixel.fun(x,y) or this.getNeighborPixel.fun(x,y)
*/
var combined = (r + g + b) / 3.000;
return [
options.red_function(r, g, b, a),
@@ -44,6 +51,17 @@ module.exports = function Dynamic(options,UI) {
];
}
/* Functions to get the neighbouring pixel by position (x,y) */
function getNeighbourPixel(pixels,curX,curY,distX,distY){
return [
pixels.get(curX+distX,curY+distY,0)
,pixels.get(curX+distX,curY+distY,1)
,pixels.get(curX+distX,curY+distY,2)
,pixels.get(curX+distX,curY+distY,3)
]
}
function output(image,datauri,mimetype){
// This output is accessible by Image Sequencer
@@ -59,6 +77,8 @@ module.exports = function Dynamic(options,UI) {
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
getNeighbourPixel: getNeighbourPixel,
getNeighborPixel: getNeighbourPixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,

View File

@@ -1,5 +1,4 @@
const _ = require('lodash')
var pace = require('pace')
//define kernels for the sobel filter
const kernelx = [[-1,0,1],[-2,0,2],[-1,0,1]],
@@ -12,7 +11,6 @@ let weakEdgePixels = []
let notInUI
module.exports = exports = function(pixels,highThresholdRatio,lowThresholdRatio,inBrowser){
notInUI = !inBrowser
if(notInUI) var progressbar1 = pace((pixels.shape[0] * pixels.shape[1]))
for(var x = 0; x < pixels.shape[0]; x++) {
angles.push([])
mags.push([])
@@ -33,7 +31,6 @@ module.exports = exports = function(pixels,highThresholdRatio,lowThresholdRatio
mags.slice(-1)[0].push(pixel[3])
angles.slice(-1)[0].push(result.angle)
if(notInUI)progressbar1.op()
}
}
@@ -75,7 +72,6 @@ function changePixel(pixels,val,a,x,y){
function nonMaxSupress(pixels) {
angles = angles.map((arr)=>arr.map(convertToDegrees))
if(notInUI) var progressbar2 = pace((pixels.shape[0] * pixels.shape[1]))
for(let i = 1;i<pixels.shape[0]-1;i++){
for(let j=1;j<pixels.shape[1]-1;j++){
@@ -118,7 +114,6 @@ function nonMaxSupress(pixels) {
else
pixels.set(i,j,3,0)
if(notInUI) progressbar2.op()
}
}
return pixels
@@ -133,7 +128,6 @@ var findMaxInMatrix = arr => Math.max(...arr.map(el=>el.map(val=>!!val?val:0)).m
function doubleThreshold(pixels,highThresholdRatio,lowThresholdRatio){
const highThreshold = findMaxInMatrix(mags) * 0.2
const lowThreshold = highThreshold * lowThresholdRatio
if(notInUI) var progressbar3 = pace((pixels.shape[0] * pixels.shape[1]))
for(let i =0;i<pixels.shape[0];i++){
for(let j=0;j<pixels.shape[1];j++){
@@ -144,7 +138,6 @@ function doubleThreshold(pixels,highThresholdRatio,lowThresholdRatio){
?strongEdgePixels.push(pixelPos)
:weakEdgePixels.push(pixelPos)
:pixels.set(i,j,3,0)
if(notInUI) progressbar3.op()
}
}

View File

@@ -15,7 +15,10 @@ module.exports = function edgeDetect(options,UI) {
var output;
// The function which is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn.
UI.onDraw(options.step);

View File

@@ -11,7 +11,10 @@ module.exports = function GreenChannel(options,UI) {
UI.onSetup(options.step);
var output;
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -12,8 +12,10 @@ module.exports = function Invert(options,UI) {
var output;
// The function which is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn.
UI.onDraw(options.step);

View File

@@ -11,7 +11,10 @@ module.exports = function NdviRed(options,UI) {
var output;
// The function which is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that a step is being drawn.
UI.onDraw(options.step);

View File

@@ -11,7 +11,10 @@ module.exports = function Saturation(options,UI) {
UI.onSetup(options.step);
var output;
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -8,7 +8,10 @@ module.exports = function SegmentedColormap(options,UI) {
var output;
// This function is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that the step is being drawn
UI.onDraw(options.step);

View File

@@ -22,12 +22,24 @@ module.exports = function PixelManipulation(image, options) {
return;
}
if(options.getNeighbourPixel){
options.getNeighbourPixel.fun = function (distX,distY) {
return options.getNeighbourPixel(pixels,x,y,distX,distY);
};
}
// iterate through pixels;
// this could possibly be more efficient; see
// https://github.com/p-v-o-s/infragram-js/blob/master/public/infragram.js#L173-L181
if(!options.inBrowser)
var pace = require('pace')((pixels.shape[0] * pixels.shape[1]))
if(!options.inBrowser){
try{
var pace = require('pace')((pixels.shape[0] * pixels.shape[1]));
}
catch(e){
options.inBrowser = true;
}
}
for(var x = 0; x < pixels.shape[0]; x++) {
for(var y = 0; y < pixels.shape[1]; y++) {

View File

@@ -15,12 +15,13 @@ var sequencer = ImageSequencer({ ui: false });
var qr = require('./images/IS-QR.js');
var test_png = require('./images/test.png.js');
var test_gif = require('./images/test.gif.js');
var spinner = require('ora')('').start()
sequencer.loadImages(test_png);
sequencer.addSteps(['invert','invert']);
test("Preload", function(t) {
sequencer.run(function(){
sequencer.run(spinner,function(){
t.end();
});
});
@@ -51,7 +52,7 @@ test("Twice inverted image is identical to original image", function (t) {
test("Decode QR module works properly :: setup", function (t) {
sequencer.loadImage(qr,function(){
this.addSteps('decode-qr').run(function(){
this.addSteps('decode-qr').run(spinner.start(),function(){
t.end();
});
})
@@ -64,7 +65,7 @@ test("Decode QR module works properly :: teardown", function (t) {
test("PixelManipulation works for PNG images", function (t) {
sequencer.loadImages(test_png,function(){
this.addSteps('invert').run(function(out){
this.addSteps('invert').run(spinner.start(),function(out){
t.equal(1,1)
t.end();
});
@@ -73,9 +74,10 @@ test("PixelManipulation works for PNG images", function (t) {
test("PixelManipulation works for GIF images", function (t) {
sequencer.loadImages(test_gif,function(){
this.addSteps('invert').run(function(out){
this.addSteps('invert').run(spinner,function(out){
t.equal(1,1)
t.end();
});
});
});
spinner.stop(true)