addSteps functionality added. Working on Node.js and Browsers

This commit is contained in:
Chinmay Pandhare
2017-06-03 20:32:12 +05:30
parent 9a1132cec6
commit 95e066fdc7
16 changed files with 34673 additions and 142 deletions

View File

@@ -23,10 +23,10 @@ module.exports = function(grunt) {
}, },
browserify: { browserify: {
dist: { // dist: {
src: ['src/ImageSequencer.js'], // src: ['src/ImageSequencer.js'],
dest: 'dist/image-sequencer.js' // dest: 'dist/image-sequencer.js'
}, // },
node: { node: {
src: ['src/ImageSequencerNode.js'], src: ['src/ImageSequencerNode.js'],
dest: 'dist/image-sequencer-node.js' dest: 'dist/image-sequencer-node.js'

34429
dist/image-sequencer-node.js vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
examples/SundarPichai.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

BIN
examples/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@@ -1,9 +1,8 @@
sharp = require('sharp'); console.log('\x1b[31m%s\x1b[0m',"This is the output of the module");
function log2(i){
console.log('\x1b[31m%s\x1b[0m:',"This is the output of the module");
console.log(sequencer.steps[i].get());
}
require('./src/ImageSequencerNode'); require('./src/ImageSequencerNode');
sequencer = ImageSequencer(); sequencer = ImageSequencer();
sequencer.loadImage('examples/grid.png'); sequencer.loadImage('sundar','examples/SundarPichai.jpeg',function(){
sequencer.addStep('do-nothing'); sequencer.loadImage('timetable','examples/test.png',function(){
sequencer.addSteps('do-nothing-pix');
});
});

View File

@@ -23,23 +23,23 @@
"bootstrap": "~3.2.0", "bootstrap": "~3.2.0",
"font-awesome": "~4.5.0", "font-awesome": "~4.5.0",
"jquery": "~2", "jquery": "~2",
"sharp": "^0.17.3" "urify": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {
"get-pixels": "~3.3.0",
"save-pixels": "~2.3.4",
"base64-stream": "~0.1.3", "base64-stream": "~0.1.3",
"buffer": "~5.0.2",
"plotly.js": "~1.21.2",
"image-filter-threshold": "~1.0.0",
"image-filter-core": "~1.0.0",
"tape": "^3.5.0",
"browserify": "13.0.0", "browserify": "13.0.0",
"buffer": "~5.0.2",
"get-pixels": "~3.3.0",
"grunt": "^0.4.5", "grunt": "^0.4.5",
"grunt-browserify": "^5.0.0", "grunt-browserify": "^5.0.0",
"grunt-contrib-concat": "^0.5.0", "grunt-contrib-concat": "^0.5.0",
"grunt-contrib-watch": "^0.6.1", "grunt-contrib-watch": "^0.6.1",
"matchdep": "^0.3.0" "image-filter-core": "~1.0.0",
"image-filter-threshold": "~1.0.0",
"matchdep": "^0.3.0",
"plotly.js": "~1.21.2",
"save-pixels": "~2.3.4",
"tape": "^3.5.0"
}, },
"homepage": "https://github.com/publiclab/image-sequencer" "homepage": "https://github.com/publiclab/image-sequencer"
} }

View File

@@ -1,15 +1,17 @@
if (typeof window !== 'undefined') window.$ = window.jQuery = require('jquery'); if (typeof window !== 'undefined') window.$ = window.jQuery = require('jquery');
else {window = global; var isBrowser = false}
ImageSequencer = function ImageSequencer(options) { ImageSequencer = function ImageSequencer(options) {
options = options || {}; options = options || {};
options.inBrowser = options.inBrowser || typeof window !== 'undefined'; options.inBrowser = options.inBrowser || isBrowser;
if (options.inBrowser) options.ui = options.ui || require('./UserInterface'); if (options.inBrowser) options.ui = options.ui || require('./UserInterface');
options.sequencerCounter = 0; options.sequencerCounter = 0;
var image, var image,
steps = [], steps = [],
modules = require('./Modules'); modules = require('./Modules'),
images = [];
// 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');
@@ -99,7 +101,7 @@ ImageSequencer = function ImageSequencer(options) {
} }
function log(msg) { function log(msg) {
$('.log').append(msg + ' at ' + new Date()); // $('.log').append(msg + ' at ' + new Date());
console.log(msg); console.log(msg);
} }
@@ -107,10 +109,6 @@ ImageSequencer = function ImageSequencer(options) {
// i.e. from parameter // i.e. from parameter
// this could send the image to ImageSelect, or something? // this could send the image to ImageSelect, or something?
function loadImage(src, callback) { function loadImage(src, callback) {
if (typeof(window) != "undefined")
for(var variable in window)
if(window[variable] == this)
options.instanceName = variable;
image = new Image(); image = new Image();
image.onload = function() { image.onload = function() {
run(image); run(image);
@@ -123,6 +121,7 @@ ImageSequencer = function ImageSequencer(options) {
return { return {
options: options, options: options,
loadImage: loadImage, loadImage: loadImage,
images: images,
addStep: addStep, addStep: addStep,
removeStep: removeStep, removeStep: removeStep,
run: run, run: run,

View File

@@ -1,84 +1,99 @@
if (typeof window !== 'undefined') {window.$ = window.jQuery = require('jquery'); isBrowser = true}
else {window = global; var isBrowser = false}
ImageSequencer = function ImageSequencer(options) { ImageSequencer = function ImageSequencer(options) {
options = options || {}; options = options || {};
options.inBrowser = options.inBrowser || typeof window !== 'undefined'; options.inBrowser = options.inBrowser || isBrowser;
// if (options.inBrowser) options.ui = options.ui || require('./UserInterface'); // if (options.inBrowser) options.ui = options.ui || require('./UserInterface');
options.sequencerCounter = 0; options.sequencerCounter = 0;
function CImage(src) {
datauri = (options.inBrowser)?(src):require('urify')(src);
image = {
src: datauri,
mimeType: datauri.split(':')[1].split(';')[0]
}
return image;
}
var image, var image,
steps = [], steps = [],
modules = require('./ModulesNode'); modules = require('./ModulesNode'),
images = {};
// 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');
else if (options.imageUrl) loadImage(imageUrl); // else if (options.imageUrl) loadImage(imageUrl);
// soon, detect local or URL? // soon, detect local or URL?
function addStep(name, o) { function addStep(image, name, o) {
console.log('\x1b[36m%s\x1b[0m','adding step "' + name + '"'); console.log('\x1b[36m%s\x1b[0m','adding step \"' + name + '\" to \"' + image + '\".');
if (typeof(global) != "undefined")
for(var variable in global)
if(global[variable] == this)
options.instanceName = variable;
o = o || {}; o = o || {};
o.id = options.sequencerCounter++; //Gives a Unique ID to each step o.id = options.sequencerCounter++; //Gives a Unique ID to each step
o.name = o.name || name; o.name = o.name || name;
o.selector = o.selector || 'ismod-' + name; o.selector = o.selector || 'ismod-' + name;
o.container = o.container || options.selector; o.container = o.container || options.selector;
o.image = image;
var module = modules[name](o); var module = modules[name](o);
images[image].steps.push(module);
steps.push(module);
function defaultSetupModule() { function defaultSetupModule() {
if (options.ui) module.options.ui = options.ui({ if (options.ui) module.options.ui = options.ui({
selector: o.selector, selector: o.selector,
title: module.options.title, title: module.options.title,
id: o.id, id: o.id
instanceName: options.instanceName
}); });
} }
if (module.hasOwnProperty('setup')) module.setup(); // add a default UI, unless the module has one specified
else defaultSetupModule.apply(module); // run default setup() in scope of module (is this right?)
if (name === "image-select") { // run the draw method.
module.draw.call(this);
module.setup(); // just set up initial ImageSelect; it has own UI // tell the UI that a step has been added.
} else { return true;
// add a default UI, unless the module has one specified
if (module.hasOwnProperty('setup')) module.setup();
else {
defaultSetupModule.apply(module); // run default setup() in scope of module (is this right?)
}
// var previousStep = steps[steps.length - 2];
//
// if (previousStep) {
// // connect output of last step to input of this step
// previousStep.options.output = function output(image) {
// if (sequencer.steps[0].options.initialImage) {
// options.initialImage = sequencer.steps[0].options.initialImage;
// }
// log('running module "' + name + '"');
// // display the image in any available ui
// if (previousStep.options.ui && previousStep.options.ui.display) previousStep.options.ui.display(image);
// module.draw(image);
// }
// }
}
// Pre-set the initial output behavior of the final step,
// which will be changed if an additional step is added.
module.options.output = function output(image) {
// if (module.options.ui && module.options.ui.display) module.options.ui.display(image);
}
return 'Addded.';
} }
function removeStep (id) { function objTypeOf(object){
return Object.prototype.toString.call(object).split(" ")[1].slice(0,-1)
}
function addSteps(){
argtype = [];
json_q = {};
for (i in images) {
lastimage = i;
}
for (var arg in arguments) {
argtype.push(objTypeOf(arguments[arg]));
}
if (arguments.length == 1) {
if(argtype[0] == "Object")
json_q = arguments[0];
else
for (i in images)
json_q[i] = [arguments[0]];
}
else if (arguments.length == 2) {
if(argtype[1]=="String") arguments[1] = [arguments[1]];
if(argtype[0]=="String")
json_q[arguments[0]] = arguments[1];
else if(argtype[0]=="Array")
for (var i in arguments[0]) {
json_q[arguments[0][i]] = arguments[1];
}
}
for (i in json_q)
for (j in json_q[i])
addStep.call(this,i,json_q[i][j]);
}
function removeStep(image,index) {
for (i=0;i<steps.length;i++) { for (i=0;i<steps.length;i++) {
if (steps[i].options.id == id && steps[i].options.name != 'image-select'){ if (steps[i].options.id == id && steps[i].options.name != 'image-select'){
console.log('\x1b[36m%s\x1b[0m','removing step "'+steps[i].options.name+'"'); console.log('\x1b[36m%s\x1b[0m','removing step "'+steps[i].options.name+'"');
@@ -91,49 +106,65 @@ ImageSequencer = function ImageSequencer(options) {
return "Removed."; return "Removed.";
} }
// passed image is optional but you can pass a function removeSteps() {
// non-stored image through the whole steps chain if(arguments.length==1) {
function run(image) {
steps[0].draw(image); }
}
function run() {
if (arguments.length == 0)
for (image in images) {
for (i in images[image].steps)
images[image].steps[i].draw.call(this);
}
else if (objTypeOf[arguments[0]]=="Array")
for (image in arguments[0]) {
for (i in images[image].steps)
images[image].steps[i].draw.call(this);
}
else if (objTypeOf(arguments[0])=="String" && (image = arguments[0])) {
for (i in images[image].steps)
images[image].steps[i].draw.call(this);
}
} }
function log(msg) { function log(msg) {
console.log(msg); console.log(msg);
} }
// load default starting image function loadImage(name, src, callback) {
// i.e. from parameter image = {
// this could send the image to ImageSelect, or something? src: src,
function loadImage(src, callback) { steps: [{
if (typeof(global) != "undefined") options: {
for(var variable in global) id: options.sequencerCounter++,
if(global[variable] == this) name: "load-image",
options.instanceName = variable; title: "Load Image"
image = {}; },
image.src = src; draw: function() {
image.width = 0; if(arguments.length==1){
image.height = 0; this.outputData = CImage(arguments[0]);
img = sharp(image.src); return true;
img.metadata().then(function(metadata){ }
image.width = metadata.width; return false;
image.height = metadata.height; },
image.naturalWidth = metadata.width; output: CImage(src)
image.naturalHeight = metadata.height; }]
options.initialImage = image; };
run(image); images[name] = image;
if(callback) callback(image); if (callback) callback();
});
} }
return { return {
options: options, options: options,
loadImage: loadImage, loadImage: loadImage,
addStep: addStep, addSteps: addSteps,
removeStep: removeStep, removeSteps: removeSteps,
run: run, run: run,
modules: modules, modules: modules,
steps: steps, steps: steps,
images: images,
ui: options.ui ui: options.ui
} }

View File

@@ -2,5 +2,8 @@
* Core modules * Core modules
*/ */
module.exports = { module.exports = {
'do-nothing': require('./modules/DoNothingNode') 'do-nothing': require('./modules/DoNothing'),
'green-channel': require('./modules/GreenChannel'),
'ndvi-red': require('./modules/NdviRed'),
'do-nothing-pix': require('./modules/DoNothingPix')
} }

31
src/modules/DoNothing.js Normal file
View File

@@ -0,0 +1,31 @@
/*
* Demo Module. Does nothing.
*/
module.exports = function DoNothing(options) {
options = options || {};
options.title = "Do Nothing";
var image;
var output;
function draw() {
thisimage = this.images[options.image];
for (i in thisimage.steps){
if (thisimage.steps[i].options.id == options.id) pos = i;
}
olddata = thisimage.steps[i-1].output;
var newdata = JSON.parse(JSON.stringify(olddata));
thisimage.steps[i].output = {src:newdata.src,mimeType:newdata.mimeType};
}
function get() {
return image;
}
return {
options: options,
draw: draw,
get: get,
output: output
}
}

View File

@@ -1,23 +0,0 @@
/*
* Demo Module. Does nothing.
*/
module.exports = function DoNothing(options) {
options = options || {};
options.title = "Do Nothing";
var image;
function draw(inputImage) {
image = inputImage;
}
function get() {
return image;
}
return {
options: options,
draw: draw,
get: get
}
}

View File

@@ -0,0 +1,40 @@
/*
* Display only the green channel
*/
module.exports = function GreenChannel(options) {
options = options || {};
options.title = "Green channel only";
options.description = "Displays only the green channel of an image";
//function setup() {} // optional
function draw() {
images = this.images;
thisimage = images[options.image];
for (i in thisimage.steps){
if (thisimage.steps[i].options.id == options.id) pos = i;
}
olddata = thisimage.steps[i-1].output;
var newdata = JSON.parse(JSON.stringify(olddata));
function changePixel(r, g, b, a) {
return [r, g, b, a];
}
function output(image,datauri,mimetype){
images[image].steps[i].output = {src:datauri,mimeType:mimetype}
}
return require('./PixelManipulation.js')(newdata, {
output: output,
changePixel: changePixel,
format: newdata.mimeType.split('/')[1],
image: options.image
});
}
return {
options: options,
//setup: setup, // optional
draw: draw
}
}

View File

@@ -9,13 +9,26 @@ module.exports = function GreenChannel(options) {
//function setup() {} // optional //function setup() {} // optional
function draw(image) { function draw() {
images = this.images;
thisimage = images[options.image];
for (i in thisimage.steps){
if (thisimage.steps[i].options.id == options.id) pos = i;
}
olddata = thisimage.steps[i-1].output;
var newdata = JSON.parse(JSON.stringify(olddata));
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
return [0, g, 0, a]; return [0, g, 0, a];
} }
return require('./PixelManipulation.js')(image, { function output(image,datauri,mimetype){
output: options.output, images[image].steps[i].output = {src:datauri,mimeType:mimetype}
changePixel: changePixel }
return require('./PixelManipulation.js')(newdata, {
output: output,
changePixel: changePixel,
format: newdata.mimeType.split('/')[1],
image: options.image
}); });
} }

View File

@@ -9,13 +9,26 @@ module.exports = function NdviRed(options) {
//function setup() {} // optional //function setup() {} // optional
function draw(image) { function draw(image) {
images = this.images;
thisimage = images[options.image];
for (i in thisimage.steps){
if (thisimage.steps[i].options.id == options.id) pos = i;
}
olddata = thisimage.steps[i-1].output;
var newdata = JSON.parse(JSON.stringify(olddata));
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
var ndvi = 255 * (b - r) / (1.00 * b + r); var ndvi = 255 * (b - r) / (1.00 * b + r);
return [ndvi, ndvi, ndvi, a]; return [ndvi, ndvi, ndvi, a];
} }
return require('./PixelManipulation.js')(image, { function output(image,datauri,mimetype){
output: options.output, images[image].steps[i].output = {src:datauri,mimeType:mimetype}
changePixel: changePixel }
return require('./PixelManipulation.js')(newdata, {
output: output,
changePixel: changePixel,
format: newdata.mimeType.split('/')[1],
image: options.image
}); });
} }

View File

@@ -8,8 +8,6 @@ module.exports = function PixelManipulation(image, options) {
options.changePixel = options.changePixel || function changePixel(r, g, b, a) { options.changePixel = options.changePixel || function changePixel(r, g, b, a) {
return [r, g, b, a]; return [r, g, b, a];
} }
options.format = options.format || "jpg";
var getPixels = require("get-pixels"), var getPixels = require("get-pixels"),
savePixels = require("save-pixels"), savePixels = require("save-pixels"),
base64 = require('base64-stream'); base64 = require('base64-stream');
@@ -48,11 +46,9 @@ module.exports = function PixelManipulation(image, options) {
savePixels(pixels, options.format) savePixels(pixels, options.format)
.on('end', function() { .on('end', function() {
var img = new Image(); datauri = 'data:image/' + options.format + ';base64,' + buffer.read().toString();
img.src = 'data:image/' + options.format + ';base64,' + buffer.read().toString(); if (options.output) options.output(options.image,datauri,options.format);
if (options.output) options.output(img);
}).pipe(buffer); }).pipe(buffer);