diff --git a/Gruntfile.js b/Gruntfile.js index df8d9666..ffa459b5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -24,10 +24,12 @@ module.exports = function(grunt) { browserify: { dist: { - src: [ - 'src/ImageSequencer.js' - ], + src: ['src/ImageSequencer.js'], dest: 'dist/image-sequencer.js' + }, + node: { + src: ['src/ImageSequencerNode.js'], + dest: 'dist/image-sequencer-node.js' } } @@ -37,7 +39,8 @@ module.exports = function(grunt) { grunt.registerTask('default', ['watch']); grunt.registerTask('build', [ - 'browserify:dist' + // 'browserify:dist', + 'browserify:node' ]); }; diff --git a/build/config.gypi b/build/config.gypi new file mode 100644 index 00000000..66b3f9f4 --- /dev/null +++ b/build/config.gypi @@ -0,0 +1,67 @@ +# Do not edit. File was generated by node-gyp's "configure" step +{ + "target_defaults": { + "cflags": [], + "default_configuration": "Release", + "defines": [], + "include_dirs": [], + "libraries": [] + }, + "variables": { + "asan": 0, + "coverage": "false", + "debug_devtools": "node", + "force_dynamic_crt": 0, + "host_arch": "x64", + "icu_data_file": "icudt58l.dat", + "icu_data_in": "../../deps/icu-small/source/data/in/icudt58l.dat", + "icu_endianness": "l", + "icu_gyp_path": "tools/icu/icu-generic.gyp", + "icu_locales": "en,root", + "icu_path": "deps/icu-small", + "icu_small": "true", + "icu_ver_major": "58", + "llvm_version": 0, + "node_byteorder": "little", + "node_enable_d8": "false", + "node_enable_v8_vtunejit": "false", + "node_install_npm": "false", + "node_module_version": 51, + "node_no_browser_globals": "false", + "node_prefix": "/usr/local/Cellar/node/7.4.0", + "node_release_urlbase": "", + "node_shared": "false", + "node_shared_cares": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_openssl": "false", + "node_shared_zlib": "false", + "node_tag": "", + "node_use_bundled_v8": "true", + "node_use_dtrace": "true", + "node_use_etw": "false", + "node_use_lttng": "false", + "node_use_openssl": "true", + "node_use_perfctr": "false", + "node_use_v8_platform": "true", + "openssl_fips": "", + "openssl_no_asm": 0, + "shlib_suffix": "51.dylib", + "target_arch": "x64", + "uv_parent_path": "/deps/uv/", + "uv_use_dtrace": "true", + "v8_enable_gdbjit": 0, + "v8_enable_i18n_support": 1, + "v8_inspector": "true", + "v8_no_strict_aliasing": 1, + "v8_optimized_debug": 0, + "v8_random_seed": 0, + "v8_use_snapshot": "true", + "want_separate_host_toolset": 0, + "want_separate_host_toolset_mkpeephole": 0, + "xcode_version": "8.0", + "nodedir": "/Users/ccdpandhare/.node-gyp/7.4.0", + "copy_dev_lib": "true", + "standalone_static_library": 1 + } +} diff --git a/dist/image-sequencer.js b/dist/image-sequencer.js index 0412bf56..67140be9 100644 --- a/dist/image-sequencer.js +++ b/dist/image-sequencer.js @@ -35613,7 +35613,7 @@ arguments[4][54][0].apply(exports,arguments) },{"dup":54}],144:[function(require,module,exports){ -exports.lineVertex = "precision highp float;\n#define GLSLIFY 1\n\nattribute vec2 aHi, aLo, dHi, dLo;\n\nuniform vec2 scaleHi, translateHi, scaleLo, translateLo, screenShape;\nuniform float width;\n\nvarying vec2 direction;\n\n\nvec2 project_1_0(vec2 scHi, vec2 trHi, vec2 scLo, vec2 trLo, vec2 posHi, vec2 posLo) {\n return (posHi + trHi) * scHi\n + (posLo + trLo) * scHi\n + (posHi + trHi) * scLo\n + (posLo + trLo) * scLo;\n}\n\n\nvec2 project_2_1(vec2 scHi, vec2 scLo, vec2 posHi, vec2 posLo) {\n return scHi * posHi\n + scLo * posHi\n + scHi * posLo\n + scLo * posLo;\n}\n\nvoid main() {\n vec2 p = project_1_0(scaleHi, translateHi, scaleLo, translateLo, aHi, aLo);\n vec2 dir = project_2_1(scaleHi, scaleLo, dHi, dLo);\n vec2 n = 0.5 * width * normalize(screenShape.yx * vec2(dir.y, -dir.x)) / screenShape.xy;\n vec2 tangent = normalize(screenShape.xy * dir);\n if(dir.x < 0.0 || (dir.x == 0.0 && dir.y < 0.0)) {\n direction = -tangent;\n } else {\n direction = tangent;\n }\n gl_Position = vec4(p + n, 0.0, 1.0);\n}" +exports.lineVertex = "precision highp float;\n#define GLSLIFY 1\n\nattribute vec2 aHi, aLo, dHi, dLo;\n\nuniform vec2 scaleHi, translateHi, scaleLo, translateLo, screenShape;\nuniform float width;\n\nvarying vec2 direction;\n\n\nvec2 project_2_0(vec2 scHi, vec2 trHi, vec2 scLo, vec2 trLo, vec2 posHi, vec2 posLo) {\n return (posHi + trHi) * scHi\n + (posLo + trLo) * scHi\n + (posHi + trHi) * scLo\n + (posLo + trLo) * scLo;\n}\n\n\nvec2 project_1_1(vec2 scHi, vec2 scLo, vec2 posHi, vec2 posLo) {\n return scHi * posHi\n + scLo * posHi\n + scHi * posLo\n + scLo * posLo;\n}\n\nvoid main() {\n vec2 p = project_2_0(scaleHi, translateHi, scaleLo, translateLo, aHi, aLo);\n vec2 dir = project_1_1(scaleHi, scaleLo, dHi, dLo);\n vec2 n = 0.5 * width * normalize(screenShape.yx * vec2(dir.y, -dir.x)) / screenShape.xy;\n vec2 tangent = normalize(screenShape.xy * dir);\n if(dir.x < 0.0 || (dir.x == 0.0 && dir.y < 0.0)) {\n direction = -tangent;\n } else {\n direction = tangent;\n }\n gl_Position = vec4(p + n, 0.0, 1.0);\n}" exports.lineFragment = "precision highp float;\n#define GLSLIFY 1\n\nuniform vec4 color;\nuniform vec2 screenShape;\nuniform sampler2D dashPattern;\nuniform float dashLength;\n\nvarying vec2 direction;\n\nvoid main() {\n float t = fract(dot(direction, gl_FragCoord.xy) / dashLength);\n vec4 pcolor = color * texture2D(dashPattern, vec2(t, 0.0)).r;\n gl_FragColor = vec4(pcolor.rgb * pcolor.a, pcolor.a);\n}" exports.mitreVertex = "precision highp float;\n#define GLSLIFY 1\n\nattribute vec2 aHi, aLo;\n\nuniform vec2 scaleHi, translateHi, scaleLo, translateLo;\nuniform float radius;\n\n\nvec2 project_1_0(vec2 scHi, vec2 trHi, vec2 scLo, vec2 trLo, vec2 posHi, vec2 posLo) {\n return (posHi + trHi) * scHi\n + (posLo + trLo) * scHi\n + (posHi + trHi) * scLo\n + (posLo + trLo) * scLo;\n}\n\n\nvoid main() {\n vec2 p = project_1_0(scaleHi, translateHi, scaleLo, translateLo, aHi, aLo);\n gl_Position = vec4(p, 0.0, 1.0);\n gl_PointSize = radius;\n}" exports.mitreFragment = "precision mediump float;\n#define GLSLIFY 1\n\nuniform vec4 color;\n\nvoid main() {\n if(length(gl_PointCoord.xy - 0.5) > 0.25) {\n discard;\n }\n gl_FragColor = vec4(color.rgb, color.a);\n}" diff --git a/index.js b/index.js new file mode 100644 index 00000000..59c27624 --- /dev/null +++ b/index.js @@ -0,0 +1,4 @@ +require('./dist/image-sequencer-node'); +sequencer = ImageSequencer(); +sequencer.loadImage('examples/grid.png'); +sequencer.addStep('ndvi-red'); diff --git a/package.json b/package.json index 0021c47b..5928e2c0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/jywarren/image-sequencer.git" + "url": "git+https://github.com/publiclab/image-sequencer.git" }, "keywords": [ "images", @@ -17,29 +17,29 @@ "author": "Public Lab", "license": "GPL-3.0", "bugs": { - "url": "https://github.com/jywarren/image-sequencer/issues" + "url": "https://github.com/publiclab/image-sequencer/issues" }, "dependencies": { "font-awesome": "~4.5.0", "bootstrap": "~3.2.0", - "jquery": "~2" + "jquery": "~2", + "sharp": "~0.17.2" }, "devDependencies": { "get-pixels": "~3.3.0", "save-pixels": "~2.3.4", - "base64-stream": "~0.1.3", - "buffer": "~5.0.2", + "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", "grunt": "^0.4.5", "grunt-browserify": "^5.0.0", "grunt-contrib-concat": "^0.5.0", "grunt-contrib-watch": "^0.6.1", - "matchdep": "^0.3.0" + "matchdep": "^0.3.0" }, - "homepage": "https://github.com/jywarren/image-sequencer" + "homepage": "https://github.com/publiclab/image-sequencer" } diff --git a/src/ImageSequencerNode.js b/src/ImageSequencerNode.js new file mode 100644 index 00000000..bea17540 --- /dev/null +++ b/src/ImageSequencerNode.js @@ -0,0 +1,151 @@ +var sharp = require('sharp'); + +ImageSequencer = function ImageSequencer(options) { + + options = options || {}; + options.inBrowser = options.inBrowser || typeof window !== 'undefined'; + if (options.inBrowser) options.ui = options.ui || require('./UserInterface'); + options.sequencerCounter = 0; + + var image, + steps = [], + modules = require('./ModulesNode'); + + // if in browser, prompt for an image + if (options.imageSelect || options.inBrowser) addStep('image-select'); + else if (options.imageUrl) loadImage(imageUrl); + + // soon, detect local or URL? + function addStep(name, o) { + console.log('adding step "' + name + '"'); + + if (typeof(global) != "undefined") + for(var variable in global) + if(global[variable] == this) + options.instanceName = variable; + + o = o || {}; + o.id = options.sequencerCounter++; //Gives a Unique ID to each step + o.name = o.name || name; + o.selector = o.selector || 'ismod-' + name; + o.container = o.container || options.selector; + + var module = modules[name](o); + + steps.push(module); + + // function defaultSetupModule() { + // if (options.ui) module.options.ui = options.ui({ + // selector: o.selector, + // title: module.options.title, + // id: o.id, + // instanceName: options.instanceName + // }); + // } + + if (name === "image-select") { + + module.setup(); // just set up initial ImageSelect; it has own UI + + } else { + + // 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); + } + + } + + function removeStep (id) { + for (i=0;i