mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-05 16:00:01 +01:00
node test
This commit is contained in:
11
Gruntfile.js
11
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'
|
||||
]);
|
||||
|
||||
};
|
||||
|
||||
67
build/config.gypi
Normal file
67
build/config.gypi
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
2
dist/image-sequencer.js
vendored
2
dist/image-sequencer.js
vendored
@@ -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}"
|
||||
|
||||
4
index.js
Normal file
4
index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
require('./dist/image-sequencer-node');
|
||||
sequencer = ImageSequencer();
|
||||
sequencer.loadImage('examples/grid.png');
|
||||
sequencer.addStep('ndvi-red');
|
||||
14
package.json
14
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,22 +17,22 @@
|
||||
"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",
|
||||
@@ -41,5 +41,5 @@
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"matchdep": "^0.3.0"
|
||||
},
|
||||
"homepage": "https://github.com/jywarren/image-sequencer"
|
||||
"homepage": "https://github.com/publiclab/image-sequencer"
|
||||
}
|
||||
|
||||
151
src/ImageSequencerNode.js
Normal file
151
src/ImageSequencerNode.js
Normal file
@@ -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<steps.length;i++) {
|
||||
if (steps[i].options.id == id && steps[i].options.name != 'image-select'){
|
||||
console.log('removing step "'+steps[i].options.name+'"');
|
||||
// if (options.inBrowser) steps[i].options.ui.remove();
|
||||
steps.splice(i,1);
|
||||
run(options.initialImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// passed image is optional but you can pass a
|
||||
// non-stored image through the whole steps chain
|
||||
function run(image) {
|
||||
if (image) steps[1].draw(image);
|
||||
else steps[0].draw();
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
$('.log').append(msg + ' at ' + new Date());
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
// load default starting image
|
||||
// i.e. from parameter
|
||||
// this could send the image to ImageSelect, or something?
|
||||
function loadImage(src, callback) {
|
||||
if (typeof(global) != "undefined")
|
||||
for(var variable in global)
|
||||
if(global[variable] == this)
|
||||
options.instanceName = variable;
|
||||
// image = new Image();
|
||||
// image.onload = function() {
|
||||
// run(image);
|
||||
// if (callback) callback(image);
|
||||
// options.initialImage = image;
|
||||
// }
|
||||
// image.src = src;
|
||||
image = {};
|
||||
image.src = src;
|
||||
image.width = 0;
|
||||
image.height = 0;
|
||||
img = sharp(image.src);
|
||||
img.metadata().then(function(metadata){
|
||||
image.width = metadata.width;
|
||||
image.height = metadata.height;
|
||||
image.naturalWidth = metadata.width;
|
||||
image.naturalHeight = metadata.height;
|
||||
run(image);
|
||||
if(callback) callback(image);
|
||||
options.initialImage = image;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
options: options,
|
||||
loadImage: loadImage,
|
||||
addStep: addStep,
|
||||
removeStep: removeStep,
|
||||
run: run,
|
||||
modules: modules,
|
||||
steps: steps,
|
||||
ui: options.ui
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ImageSequencer;
|
||||
6
src/ModulesNode.js
Normal file
6
src/ModulesNode.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
* Core modules
|
||||
*/
|
||||
module.exports = {
|
||||
'image-threshold': require('./modules/ImageThresholdNode')
|
||||
}
|
||||
54
src/modules/ImageThresholdNode.js
Normal file
54
src/modules/ImageThresholdNode.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Image thresholding with 'image-filter-threshold'
|
||||
*/
|
||||
module.exports = function ImageThreshold(options) {
|
||||
options = options || {};
|
||||
options.title = "Threshold image";
|
||||
options.threshold = options.threshold || 30;
|
||||
|
||||
var image;
|
||||
|
||||
function draw(inputImage) {
|
||||
$(inputImage).load(function(){
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = inputImage.naturalWidth;
|
||||
canvas.height = inputImage.naturalHeight;
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(inputImage, 0, 0);
|
||||
|
||||
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
||||
var imageThreshold = require('image-filter-threshold');
|
||||
var imageFilterCore = require('image-filter-core');
|
||||
|
||||
var result = imageThreshold({
|
||||
data: imageData,
|
||||
threshold: options.threshold
|
||||
}).then(function (imageData) {
|
||||
image = {};
|
||||
image.src = src;
|
||||
image.width = 0;
|
||||
image.height = 0;
|
||||
img = sharp(image.src);
|
||||
img.metadata().then(function(metadata){
|
||||
image.width = metadata.width;
|
||||
image.height = metadata.height;
|
||||
image.naturalWidth = metadata.width;
|
||||
image.naturalHeight = metadata.height;
|
||||
if (options.output) options.output(image);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function get() {
|
||||
return image;
|
||||
}
|
||||
|
||||
return {
|
||||
options: options,
|
||||
draw: draw,
|
||||
get: get
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user