mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-14 04:10:04 +01:00
Compare commits
2 Commits
origin/mco
...
Codecov-co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e562cae6a0 | ||
|
|
40c91483ab |
@@ -1 +0,0 @@
|
|||||||
dist/*
|
|
||||||
36
.eslintrc.js
36
.eslintrc.js
@@ -1,36 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
'env': {
|
|
||||||
'browser': true,
|
|
||||||
'commonjs': true,
|
|
||||||
'es6': true,
|
|
||||||
'node': true
|
|
||||||
},
|
|
||||||
'extends': 'eslint:recommended',
|
|
||||||
'globals': {
|
|
||||||
'Atomics': 'readonly',
|
|
||||||
'SharedArrayBuffer': 'readonly'
|
|
||||||
},
|
|
||||||
'parserOptions': {
|
|
||||||
'ecmaVersion': 2018
|
|
||||||
},
|
|
||||||
'rules': {
|
|
||||||
'indent': ['error',2],
|
|
||||||
'linebreak-style': ['error','unix'],
|
|
||||||
'quotes': ['error','single'],
|
|
||||||
'semi': ['error','always'], //
|
|
||||||
'no-undef': 0,
|
|
||||||
'no-console': 'off',
|
|
||||||
'no-unused-vars': 'off',
|
|
||||||
'no-redeclare': 'off',
|
|
||||||
'no-inner-declarations':'off',
|
|
||||||
'no-empty':'off',
|
|
||||||
'no-mixed-spaces-and-tabs':'off',
|
|
||||||
'no-self-assign':'off',
|
|
||||||
'no-constant-condition':'off',
|
|
||||||
'no-dupe-keys':'off',
|
|
||||||
'space-infix-ops': ['error', {'int32Hint': false}], // Enforce spaces around operators
|
|
||||||
'comma-spacing': ['error', { "before": false, "after": true }], // require spacing after a comma
|
|
||||||
'comma-style': ['error', 'last'], // requires comma after and on the same line
|
|
||||||
'no-trailing-spaces': ['error', { 'skipBlankLines': true }], // Disallows trailing whitespace on end of lines and empty lines
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
sudo: required
|
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
|
- '6'
|
||||||
- '8'
|
- '8'
|
||||||
- '10'
|
- '10'
|
||||||
env:
|
env:
|
||||||
- CXX=g++-4.8
|
- CXX=g++-4.8
|
||||||
before_script:
|
before_script:
|
||||||
- npm install grunt-cli -g # for "grunt build"
|
- npm install grunt-cli -g # for "grunt build"
|
||||||
|
- npm install jasmine -g
|
||||||
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||||
- chmod +x ./cc-test-reporter
|
- chmod +x ./cc-test-reporter
|
||||||
- ./cc-test-reporter before-build
|
- ./cc-test-reporter before-build
|
||||||
@@ -25,10 +26,6 @@ addons:
|
|||||||
packages:
|
packages:
|
||||||
- g++-4.8
|
- g++-4.8
|
||||||
- xvfb # for tape-run
|
- xvfb # for tape-run
|
||||||
before_install:
|
|
||||||
- sudo apt-get update
|
|
||||||
- sudo apt-get install xserver-xorg-dev libxext-dev libxi-dev
|
|
||||||
- sudo apt-get install -y build-essential libxi-dev libglu1-mesa-dev libglew-dev pkg-config libglu1-mesa-dev freeglut3-dev mesa-common-dev
|
|
||||||
install:
|
install:
|
||||||
- export DISPLAY=':99.0' # for tape-run
|
- export DISPLAY=':99.0' # for tape-run
|
||||||
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & # for tape-run
|
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & # for tape-run
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ Contributing to Image Sequencer
|
|||||||
|
|
||||||
Happily accepting pull requests; to edit the core library, modify files in `./src/`. To build, run `npm install` followed by `grunt build`.
|
Happily accepting pull requests; to edit the core library, modify files in `./src/`. To build, run `npm install` followed by `grunt build`.
|
||||||
|
|
||||||
On ARM based devices, the `gl` module may require some libraries to be re-installed:
|
|
||||||
|
|
||||||
`sudo apt-get install -y build-essential libxi-dev libglu1-mesa-dev libglew-dev pkg-config` -- see https://github.com/stackgl/headless-gl#ubuntudebian for more.
|
|
||||||
|
|
||||||
Most contribution (we imagine) would be in the form of API-compatible modules, which need not be directly included.
|
Most contribution (we imagine) would be in the form of API-compatible modules, which need not be directly included.
|
||||||
|
|
||||||
## Jump To
|
## Jump To
|
||||||
@@ -16,7 +12,6 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
|
|||||||
* [Info File](#info-file)
|
* [Info File](#info-file)
|
||||||
* [Ideas](#Contribution-ideas)
|
* [Ideas](#Contribution-ideas)
|
||||||
* [Grunt Tasks](#grunt-tasks)
|
* [Grunt Tasks](#grunt-tasks)
|
||||||
* [UI Helper Methods](#ui-helper-methods)
|
|
||||||
|
|
||||||
****
|
****
|
||||||
|
|
||||||
@@ -280,7 +275,6 @@ module.exports = function ModuleName(options,UI) {
|
|||||||
|
|
||||||
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.
|
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
|
### Module example
|
||||||
|
|
||||||
See existing module `channel` for an example: https://github.com/publiclab/image-sequencer/blob/main/src/modules/Channel/Module.js
|
See existing module `channel` for an example: https://github.com/publiclab/image-sequencer/blob/main/src/modules/Channel/Module.js
|
||||||
@@ -369,29 +363,7 @@ module.exports =
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Linting
|
|
||||||
|
|
||||||
We are now using `eslint` and `husky` to help lint and format our code each time we commit. Eslint defines coding standards and helps in cleaning up the code. To run eslint for checking errors globally or within a specific file run:
|
|
||||||
|
|
||||||
```
|
|
||||||
npx eslint .
|
|
||||||
|
|
||||||
npx eslint <file path>
|
|
||||||
```
|
|
||||||
And to fix those errors globally or in a file, run these in your terminal:
|
|
||||||
```
|
|
||||||
npx eslint . --fix
|
|
||||||
|
|
||||||
npx eslint <file path> --fix
|
|
||||||
```
|
|
||||||
Be sure to not include the angular brackets(<>).
|
|
||||||
|
|
||||||
Husky ensures automation of the above steps with git-hooks(eg. git add,git commit..). However we don't want to check and fix changes of the entire codebase with each commit and that the fixes made by eslint appear unstaged and require us to commit them again and that is where lint-staged helps.
|
|
||||||
|
|
||||||
If we want `husky` to not verify the commit and push it anyway, use `git commit -m "message" --no-verify.`
|
|
||||||
|
|
||||||
## Grunt Tasks
|
## Grunt Tasks
|
||||||
|
|
||||||
This repository has different grunt tasks for different uses. The source code is in the [Gruntfile](https://github.com/publiclab/image-sequencer/blob/main/Gruntfile.js).
|
This repository has different grunt tasks for different uses. The source code is in the [Gruntfile](https://github.com/publiclab/image-sequencer/blob/main/Gruntfile.js).
|
||||||
|
|
||||||
The following command is used for running the tasks: `grunt [task-name]`. Here `[task-name]` should be replaced by the name of the task to be run. To run the default task run `grunt` without any options.
|
The following command is used for running the tasks: `grunt [task-name]`. Here `[task-name]` should be replaced by the name of the task to be run. To run the default task run `grunt` without any options.
|
||||||
@@ -403,58 +375,3 @@ The following command is used for running the tasks: `grunt [task-name]`. Here `
|
|||||||
4. **serve**: Compiles the dist files as in the **compile** task and starts a local server on `localhost:3000` to host the demo site in `/examples/` directory. Also runs the **watch** task.
|
4. **serve**: Compiles the dist files as in the **compile** task and starts a local server on `localhost:3000` to host the demo site in `/examples/` directory. Also runs the **watch** task.
|
||||||
5. **production**: Compiles and minifies dist files in `/dist/image-sequencer.js` and `/dist/image-sequencer-ui.js` without the `.min.js` extension to include minified files in the demo site. This script should only be used in production mode while deploying.
|
5. **production**: Compiles and minifies dist files in `/dist/image-sequencer.js` and `/dist/image-sequencer-ui.js` without the `.min.js` extension to include minified files in the demo site. This script should only be used in production mode while deploying.
|
||||||
6. **default**: Runs the **watch** task as default.
|
6. **default**: Runs the **watch** task as default.
|
||||||
|
|
||||||
## UI Helper Methods
|
|
||||||
|
|
||||||
### scopeQuery
|
|
||||||
|
|
||||||
###### Path: `/examples/lib/scopeQuery.js`
|
|
||||||
|
|
||||||
The method returns a scoped `jQuery` object which only searches for elements inside a given scope (a DOM element).
|
|
||||||
|
|
||||||
To use the method,
|
|
||||||
* import the `scopeSelector` and `scopeSelectorAll` methods from `lib/scopeQuery.js`
|
|
||||||
* call the methods with scope as a parameter
|
|
||||||
|
|
||||||
```js
|
|
||||||
var scopeQuery = require('./scopeQuery');
|
|
||||||
|
|
||||||
var $step = scopeQuery.scopeSelector(scope),
|
|
||||||
$stepAll = scopeQuery.scopeSelectorAll(scope);
|
|
||||||
```
|
|
||||||
This will return an object with a constructor which returns a `jQuery` object (from inside the scope) but with new `elem` and `elemAll` methods.
|
|
||||||
|
|
||||||
#### Methods of the Returned Object
|
|
||||||
* `elem()`: Selects an element inside the scope.
|
|
||||||
* `elemAll()`: Selects all the instances of a given element inside the scope.
|
|
||||||
* `getScope()`: Returns the scope as a DOM element.
|
|
||||||
* `getDomElem()`: Returns the scoped element as a DOM element instead of a jquery object.
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
```js
|
|
||||||
//The scope is a div element with id=“container“ and there are three divs in it
|
|
||||||
//with ids „1“, „2“, and „3“, and all of them have a „child“ class attribute
|
|
||||||
|
|
||||||
var $step = require('./scopeQuery').scopeSelector(document.getElementById('container'));
|
|
||||||
|
|
||||||
$step('#1'); // returns the div element with id=“1“
|
|
||||||
$step('#1').hide().elemAll('.child').fadeOut(); // abruptly hides the div element with id=“1“ and fades out all other div elements
|
|
||||||
```
|
|
||||||
|
|
||||||
These two methods are chainable and will always return elements from inside the scope.
|
|
||||||
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
Instead of using
|
|
||||||
|
|
||||||
```js
|
|
||||||
$(step.ui.querySelector('query')).show().hide();
|
|
||||||
$(step.ui.querySelectorAll('q2')).show().hide();
|
|
||||||
```
|
|
||||||
The following code can be used
|
|
||||||
|
|
||||||
```js
|
|
||||||
$step('query').show().hide();
|
|
||||||
$stepAll('q2').show().hide();
|
|
||||||
```
|
|
||||||
|
|||||||
56
Gruntfile.js
56
Gruntfile.js
@@ -1,76 +1,76 @@
|
|||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
grunt.loadNpmTasks('grunt-browserify');
|
grunt.loadNpmTasks("grunt-browserify");
|
||||||
grunt.loadNpmTasks('grunt-contrib-uglify-es');
|
grunt.loadNpmTasks("grunt-contrib-uglify-es");
|
||||||
grunt.loadNpmTasks('grunt-browser-sync');
|
grunt.loadNpmTasks("grunt-browser-sync");
|
||||||
|
|
||||||
require('matchdep')
|
require("matchdep")
|
||||||
.filterDev('grunt-*')
|
.filterDev("grunt-*")
|
||||||
.forEach(grunt.loadNpmTasks);
|
.forEach(grunt.loadNpmTasks);
|
||||||
|
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
pkg: grunt.file.readJSON("package.json"),
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
options: {
|
options: {
|
||||||
livereload: true
|
livereload: true
|
||||||
},
|
},
|
||||||
source: {
|
source: {
|
||||||
files: ['src/**/*', 'Gruntfile.js', 'examples/lib/*', 'examples/demo.js'],
|
files: ["src/**/*", "Gruntfile.js", "examples/lib/*", "examples/demo.js"],
|
||||||
tasks: ['compile']
|
tasks: ["compile"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
browserify: {
|
browserify: {
|
||||||
core: {
|
core: {
|
||||||
src: ['src/ImageSequencer.js'],
|
src: ["src/ImageSequencer.js"],
|
||||||
dest: 'dist/image-sequencer.js'
|
dest: "dist/image-sequencer.js"
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
src: ['examples/demo.js'],
|
src: ["examples/demo.js"],
|
||||||
dest: 'dist/image-sequencer-ui.js'
|
dest: "dist/image-sequencer-ui.js"
|
||||||
},
|
},
|
||||||
prodcore: {
|
prodcore: {
|
||||||
src: ['src/ImageSequencer.js'],
|
src: ["src/ImageSequencer.js"],
|
||||||
dest: 'dist/image-sequencer.brow.js'
|
dest: "dist/image-sequencer.brow.js"
|
||||||
},
|
},
|
||||||
produi: {
|
produi: {
|
||||||
src: ['examples/demo.js'],
|
src: ["examples/demo.js"],
|
||||||
dest: 'dist/image-sequencer-ui.brow.js'
|
dest: "dist/image-sequencer-ui.brow.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
uglify: {
|
uglify: {
|
||||||
core: {
|
core: {
|
||||||
src: ['./dist/image-sequencer.js'],
|
src: ["./dist/image-sequencer.js"],
|
||||||
dest: './dist/image-sequencer.min.js'
|
dest: "./dist/image-sequencer.min.js"
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
src: ['dist/image-sequencer-ui.js'],
|
src: ['dist/image-sequencer-ui.js'],
|
||||||
dest: 'dist/image-sequencer-ui.min.js'
|
dest: 'dist/image-sequencer-ui.min.js'
|
||||||
},
|
},
|
||||||
prodcore: {
|
prodcore: {
|
||||||
src: ['dist/image-sequencer.brow.js'],
|
src: ["dist/image-sequencer.brow.js"],
|
||||||
dest: 'dist/image-sequencer.js'
|
dest: "dist/image-sequencer.js"
|
||||||
},
|
},
|
||||||
produi: {
|
produi: {
|
||||||
src: ['dist/image-sequencer-ui.brow.js'],
|
src: ["dist/image-sequencer-ui.brow.js"],
|
||||||
dest: 'dist/image-sequencer-ui.js'
|
dest: "dist/image-sequencer-ui.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
browserSync: {
|
browserSync: {
|
||||||
dev: {
|
dev: {
|
||||||
options: {
|
options: {
|
||||||
watchTask: true,
|
watchTask: true,
|
||||||
server: './'
|
server: "./"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Default (development): Watch files and build on change. */
|
/* Default (development): Watch files and build on change. */
|
||||||
grunt.registerTask('default', ['watch']);
|
grunt.registerTask("default", ["watch"]);
|
||||||
grunt.registerTask('build', ['browserify:core', 'browserify:ui', 'uglify:core', 'uglify:ui']);
|
grunt.registerTask("build", ["browserify:core", "browserify:ui", "uglify:core", "uglify:ui"]);
|
||||||
grunt.registerTask('serve', ['browserify:core', 'browserify:ui', 'browserSync', 'watch']);
|
grunt.registerTask("serve", ["browserify:core", "browserify:ui", "browserSync", "watch"]);
|
||||||
grunt.registerTask('compile', ['browserify:core', 'browserify:ui']);
|
grunt.registerTask("compile", ["browserify:core", "browserify:ui"]);
|
||||||
grunt.registerTask('production', ['browserify:prodcore', 'browserify:produi', 'uglify:prodcore', 'uglify:produi']);
|
grunt.registerTask("production", ["browserify:prodcore", "browserify:produi", "uglify:prodcore", "uglify:produi"]);
|
||||||
};
|
};
|
||||||
|
|||||||
63
README.md
63
README.md
@@ -2,7 +2,7 @@ Image Sequencer
|
|||||||
====
|
====
|
||||||
|
|
||||||
|
|
||||||
[](https://travis-ci.org/publiclab/image-sequencer) [](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) [](https://codecov.io/gh/publiclab/image-sequencer)
|
[](https://travis-ci.org/publiclab/image-sequencer) [](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) 
|
||||||
|
|
||||||
- **Latest Stable Demo**: https://sequencer.publiclab.org
|
- **Latest Stable Demo**: https://sequencer.publiclab.org
|
||||||
- **Latest Beta Demo**: https://beta.sequencer.publiclab.org
|
- **Latest Beta Demo**: https://beta.sequencer.publiclab.org
|
||||||
@@ -59,7 +59,7 @@ A diagram of this running 5 steps on a single sample image may help explain how
|
|||||||
This library conveniently works in the browser, in Node, and on the command line (CLI).
|
This library conveniently works in the browser, in Node, and on the command line (CLI).
|
||||||
|
|
||||||
### Unix based platforms
|
### Unix based platforms
|
||||||
You can set up a local environment to test the UI with `sudo npm run setup` followed by `npm start`.
|
You can set up a local environment to test the UI with `npm run setup` followed by `npm start`.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
Our npm scripts do not support windows shells, please run the following snippet in PowerShell.
|
Our npm scripts do not support windows shells, please run the following snippet in PowerShell.
|
||||||
@@ -201,17 +201,15 @@ var sequencer = ImageSequencer();
|
|||||||
### Loading an Image into the Sequencer
|
### Loading an Image into the Sequencer
|
||||||
|
|
||||||
The `loadImage` method is used to load an image into the sequencer. It accepts
|
The `loadImage` method is used to load an image into the sequencer. It accepts
|
||||||
an image `src`, either a URL or a data-url. The method also accepts an optional callback.
|
a name and an image. The method also accepts an optional callback.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
sequencer.loadImage(image_src,optional_callback);
|
sequencer.loadImage(image_src,optional_callback);
|
||||||
```
|
```
|
||||||
|
|
||||||
On `Node.js` the `image_src` may be a DataURI or a local path or a URL.
|
On `Node.js` the `image_src` may be a DataURI or a local path or a URL.
|
||||||
|
|
||||||
On browsers, it may be a DatURI, a local image or a URL (Unless this violates
|
On browsers, it may be a DatURI, a local image or a URL (Unless this violates
|
||||||
CORS Restrictions). To sum up, these are accepted:
|
CORS Restrictions). To sum up, these are accepted:
|
||||||
|
|
||||||
* Images in the same domain (or directory - for a local implementation)
|
* Images in the same domain (or directory - for a local implementation)
|
||||||
* CORS-Proof images in another domain.
|
* CORS-Proof images in another domain.
|
||||||
* DataURLs
|
* DataURLs
|
||||||
@@ -245,38 +243,6 @@ to be added, in that particular order.
|
|||||||
optional_otions is just an optional parameter, in object form, which you might
|
optional_otions is just an optional parameter, in object form, which you might
|
||||||
want to provide to the modules.
|
want to provide to the modules.
|
||||||
|
|
||||||
A variety of syntaxes are supported by Image Sequencer to add multiple steps and configurations quickly for module chaining. The project supports the string syntax, designed to be compact and URL friendly, and JSON, for handling more complex sequences. This can be achieved by passing strings to `sequencer.addStep()`:
|
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.addSteps('invert,channel');
|
|
||||||
sequencer.addSteps(['invert','channel']);
|
|
||||||
```
|
|
||||||
|
|
||||||
For passing default configurations ({} is optional):
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.addSteps('brightness{}');
|
|
||||||
```
|
|
||||||
|
|
||||||
For passing custom configurations:
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.addSteps('brightness{brightness:80}');
|
|
||||||
```
|
|
||||||
|
|
||||||
For passing multiple custom configurations:
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.addSteps('crop{x:120|y:90}')
|
|
||||||
```
|
|
||||||
|
|
||||||
For passing multiple custom configurable modules:
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.addSteps('crop{x:130|y:80},brightness{brightness:80}')
|
|
||||||
```
|
|
||||||
|
|
||||||
return value: **`sequencer`** (To allow method chaining)
|
return value: **`sequencer`** (To allow method chaining)
|
||||||
|
|
||||||
|
|
||||||
@@ -432,7 +398,7 @@ Image sequencer supports stringifying a sequence which is appended to the url an
|
|||||||
channel{channel:green},invert{}
|
channel{channel:green},invert{}
|
||||||
```
|
```
|
||||||
|
|
||||||
The use of `()` in place of `{}` for backward compatibility with older links is now **deprecated**. (There is no longer support for the following syntax, and should be avoided)
|
Sequencer also supports the use of `()` in place of `{}` for backward compatibility with older links. (This syntax is deprecated and should be avoided as far as possible)
|
||||||
```
|
```
|
||||||
channel(channel:green),invert()
|
channel(channel:green),invert()
|
||||||
```
|
```
|
||||||
@@ -578,24 +544,3 @@ sequencer2.run();
|
|||||||
This method returns an object which defines the name and inputs of the modules. If a module name (hyphenated) is passed in the method, then only the details of that module are returned.
|
This method returns an object which defines the name and inputs of the modules. If a module name (hyphenated) is passed in the method, then only the details of that module are returned.
|
||||||
|
|
||||||
The `notify` function takes two parameters `msg` and `id`, former being the message to be displayed on console (in case of CLI and node ) and a HTML component(in browser). The id is optional and is useful for HTML interface to give appropriate IDs.
|
The `notify` function takes two parameters `msg` and `id`, former being the message to be displayed on console (in case of CLI and node ) and a HTML component(in browser). The id is optional and is useful for HTML interface to give appropriate IDs.
|
||||||
|
|
||||||
## Using WebAssembly for heavy pixel processing
|
|
||||||
|
|
||||||
Any module which uses the `changePixel` function gets WebAssembly acceleration (`wasm`). Both node and browser code use WebAssembly and the only code which falls back to non-`wasm` code is the [browserified unit tests](https://github.com/publiclab/image-sequencer/blob/main/test/core/sequencer/benchmark.js).
|
|
||||||
|
|
||||||
The main advantage we get using `wasm` is blazing fast speed attained in processing pixels for many modules that is very clear from [checking module benchmarks](https://travis-ci.org/publiclab/image-sequencer/jobs/544415673#L1931).
|
|
||||||
|
|
||||||
|
|
||||||
The only limitation is that browser and node code for `wasm` had to be written separately, and switched between. This is because in browser we use `fetch` to retrieve the compiled `wasm` program while in node we use the `fs` module, each of which cannot be used in the other's environment.
|
|
||||||
|
|
||||||
|
|
||||||
`wasm` mode is enabled by default. If you need to force this mode to be on or off, you can use the `useWasm` option when initializing ImageSequencer:
|
|
||||||
|
|
||||||
```js
|
|
||||||
let sequencer = ImageSequencer({useWasm:true}) // for wasm mode or simply
|
|
||||||
|
|
||||||
let sequencer = ImageSequencer() // also for wasm mode i.e. default mode
|
|
||||||
|
|
||||||
let sequencer = ImageSequencer({useWasm:false}) //for non-wasm mode
|
|
||||||
|
|
||||||
```
|
|
||||||
BIN
dist/manipulation.wasm
vendored
BIN
dist/manipulation.wasm
vendored
Binary file not shown.
706
docs/MODULES.md
706
docs/MODULES.md
@@ -3,229 +3,48 @@ Documentation of various Modules
|
|||||||
|
|
||||||
List of Module Documentations
|
List of Module Documentations
|
||||||
|
|
||||||
1. [Add QR](#Add-QR-module)
|
1. [Crop](#crop-module)
|
||||||
2. [Average](#average-module)
|
2. [Segmented-Colormap](#segmented-colormap-module)
|
||||||
3. [Blend](#blend-module)
|
3. [FisheyeGl](#fisheyeGl-module)
|
||||||
4. [Blur](#blur-module)
|
4. [Add QR](#Add-QR-module)
|
||||||
5. [Brightness](#brightness-module)
|
5. [Average](#average-module)
|
||||||
6. [Channel](#channel-module)
|
6. [Blend](#blend-module)
|
||||||
7. [Colorbar](#colorbar-module)
|
7. [Blur](#blur-module)
|
||||||
8. [Colormap](#colormap-module)
|
8. [Brightness](#brightness-module)
|
||||||
9. [ColorTemperature](#color-temperature)
|
9. [Channel](#channel-module)
|
||||||
10. [Contrast](#contrast-module)
|
10. [Colorbar](#colorbar-module)
|
||||||
11. [Convolution](#convolution-module)
|
11. [Colormap](#colormap-module)
|
||||||
12. [Crop](#crop-module)
|
12. [Contrast](#contrast-module)
|
||||||
13. [DecodeQr](#decodeQr-module)
|
13. [Convolution](#convolution-module)
|
||||||
14. [Dither](#dither-module)
|
14. [DecodeQr](#decodeQr-module)
|
||||||
15. [DrawRectangle](#draw-rectangle-module)
|
15. [Dither](#dither-module)
|
||||||
16. [Dynamic](#dynamic-module)
|
16. [DrawRectangle](#draw-rectangle-module)
|
||||||
17. [Edge-Detect](#edge-detect-module)
|
17. [Dynamic](#dynamic-module)
|
||||||
18. [FisheyeGl](#fisheyeGl-module)
|
18. [Edge-Detect](#edge-detect-module)
|
||||||
19. [FlipImage](#flipimage-module)
|
19. [FlipImage](#flipimage-module)
|
||||||
20. [Gamma-Correction](#gamma-correction-module)
|
20. [Gamma-Correction](#gamma-correction-module)
|
||||||
21. [Gradient](#gradient-module)
|
21. [Gradient](#gradient-module)
|
||||||
22. [Grid-Overlay](#grid-overlay)
|
22. [Histogram](#histogram-module)
|
||||||
23. [Histogram](#histogram-module)
|
23. [Import-image](#import-image-module)
|
||||||
24. [Import-image](#import-image-module)
|
24. [Invert](#invert-module)
|
||||||
25. [Invert](#invert-module)
|
25. [Ndvi](#ndvi-module)
|
||||||
26. [MinifyImage](#minify-image)
|
26. [Ndvi-Colormap](#ndvi-colormap-module)
|
||||||
27. [Ndvi](#ndvi-module)
|
27. [Overlay](#overlay-module)
|
||||||
28. [Ndvi-Colormap](#ndvi-colormap-module)
|
28. [PaintBucket](#paint-bucket-module)
|
||||||
29. [Overlay](#overlay-module)
|
29. [Resize](#resize-module)
|
||||||
30. [PaintBucket](#paint-bucket-module)
|
30. [ReplaceColor](#replacecolor-module)
|
||||||
31. [ReplaceColor](#replacecolor-module)
|
31. [Rotate](#rotate-module)
|
||||||
32. [Resize](#resize-module)
|
32. [Saturation](#saturation-module)
|
||||||
33. [Rotate](#rotate-module)
|
33. [Threshold](#threshold)
|
||||||
34. [Saturation](#saturation-module)
|
34. [Tint](#tint)
|
||||||
35. [Segmented-Colormap](#segmented-colormap-module)
|
35. [ColorTemperature](#color-temperature)
|
||||||
36. [Text-Overlay](#text-overlay)
|
36. [Grid-Overlay](#grid-overlay)
|
||||||
37. [Threshold](#threshold)
|
|
||||||
38. [Tint](#tint)
|
|
||||||
|
|
||||||
|
|
||||||
## add-qr-module
|
|
||||||
|
|
||||||
This module Adds QR corresponding to the given string.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('add-qr',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* size : size of QR code in pixels (default 200)
|
|
||||||
* qrCodeString : input string to generate QR code
|
|
||||||
|
|
||||||
|
|
||||||
## average-module
|
|
||||||
|
|
||||||
This module is used for averaging all the pixels of the image.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('average',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## blend-module
|
|
||||||
|
|
||||||
This module is used for blending two images .
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('blend',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* offset: step of image with which current image is to be blended(Two steps back is -2, three steps back is -3 etc; default -2)
|
|
||||||
* func: function used to blend two images (default : function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] })
|
|
||||||
|
|
||||||
## Blob Analysis
|
|
||||||
|
|
||||||
This module uses Opencv.js for detecting and marking blob/region in microscopic images. It requires an opencv.js file to
|
|
||||||
be loaded before using the functionalities which is currently being loaded to the webpage via script.It supports both environments, Node.js and browser for processing.
|
|
||||||
|
|
||||||
As the size of opencv.js file is quite large, the future versions will focus on loading it asynchronously, on demand of the the module to optimise performance.
|
|
||||||
|
|
||||||
#### Usage
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('blob-analysis')
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
## blur-module
|
|
||||||
|
|
||||||
This module is used for applying a Gaussian blur effect.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('blur',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* blur : Intensity of Gaussian blur (0 to 5; default 2)
|
|
||||||
|
|
||||||
|
|
||||||
## brightness-module
|
|
||||||
|
|
||||||
This module is used for changing the brightness of the image.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('brightness',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* brightness : brightness of the image in percentage (0 to 100; default 100)
|
|
||||||
|
|
||||||
|
|
||||||
## channel-module
|
|
||||||
|
|
||||||
This module is used for forming a grayscale image by applying one of the three primary colors.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('channel',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* channel : color of the channel (red, green, blue; default green)
|
|
||||||
|
|
||||||
|
|
||||||
## colorbar-module
|
|
||||||
|
|
||||||
This module is used for displaying an image with a colorbar.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('colorbar',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* colormap : Name of the Colormap(default, greyscale, stretched, fastie, brntogrn, blutoredjet, colors16; default: default)
|
|
||||||
* x : X-position of the image on which the new image is overlayed (default 0)
|
|
||||||
* y : Y-position of the image on which the new image is overlayed (default 0)
|
|
||||||
* h : height of resulting cropped image (default : 50% of input image width )
|
|
||||||
|
|
||||||
|
|
||||||
## colormap-module
|
|
||||||
|
|
||||||
This module is used for mapping brightness values (average of red, green & blue) to a given color lookup table, made up of a set of one more color gradients.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('colormap',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* colormap : Name of the Colormap ( greyscale, stretched, fastie, brntogrn, blutoredjet, colors16)
|
|
||||||
|
|
||||||
|
|
||||||
## Color Temperature
|
|
||||||
|
|
||||||
This changes the color temperature of the image.
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('color-temperature',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* temperature : temperature between 0 - 40,000 kelvin (default 6000)
|
|
||||||
|
|
||||||
|
|
||||||
## contrast-module
|
|
||||||
|
|
||||||
This module is used for changing the contrast of the image.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('contrast',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* contrast : contrast for the given image (-100 to 100; default : 70)
|
|
||||||
|
|
||||||
|
|
||||||
## convolution-module
|
|
||||||
|
|
||||||
This module is used for performing image-convolution.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('convolution',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* constantFactor : a constant factor, multiplies all the kernel values by that factor (default : 1/9)
|
|
||||||
* kernelValues : nine space separated numbers representing the kernel values in left to right and top to bottom format(default : 1 1 1 1 1 1 1 1 1)
|
|
||||||
|
|
||||||
|
|
||||||
## crop-module
|
## crop-module
|
||||||
|
|
||||||
This module is used to crop an image.
|
This module is used to crop an image.
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -245,90 +64,34 @@ Where `options` is an object having the properties `x`, `y`, `w`, `h`. This diag
|
|||||||
* `options.h` : half of image height
|
* `options.h` : half of image height
|
||||||
|
|
||||||
|
|
||||||
## decodeQr-module
|
## segmented-colormap-module
|
||||||
|
|
||||||
|
This module is used to map the pixels of the image to a segmented colormap.
|
||||||
|
|
||||||
This module is used for decoding a QR in image (if present).
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
sequencer.loadImage('PATH')
|
sequencer.loadImage('PATH')
|
||||||
.addSteps('decode-qr',options)
|
.addSteps('segmented-colormap',options)
|
||||||
.run()
|
.run()
|
||||||
```
|
```
|
||||||
|
|
||||||
## dither-module
|
where `options` is an object with the property `colormap`. `options.colormap` can be:
|
||||||
|
|
||||||
This module approximates a color from a mixture of other colors when the required color is not available, creating illusions of the color that is not present actually.
|
* "default" : [[0, [0, 0, 255], [38, 195, 195]], [0.5, [0, 150, 0], [255, 255, 0]], [0.75, [255, 255, 0], [255, 50, 50]]]
|
||||||
|
|
||||||
[more info on wikipedia](https://en.wikipedia.org/wiki/Dither)
|
* "greyscale" : [[0, [0, 0, 0], [255, 255, 255]], [1, [255, 255, 255], [255, 255, 255]]]
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
* "stretched" : [[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]]]
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('dither',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* dither : Can select the name of the Dithering Algorithm(default none)
|
|
||||||
|
|
||||||
|
* "fastie" : [[0, [255, 255, 255], [0, 0, 0]], [0.167, [0, 0, 0], [255, 255, 255]], [0.33, [255, 255, 255], [0, 0, 0]], [0.5, [0, 0, 0], [140, 140, 255]], [0.55, [140, 140, 255], [0, 255, 0]], [0.63, [0, 255, 0], [255, 255, 0]], [0.75, [255, 255, 0], [255, 0, 0]], [0.95, [255, 0, 0], [255, 0, 255]]]
|
||||||
|
|
||||||
## draw-rectangle-module
|
* A custom array.
|
||||||
|
|
||||||
This module helps to draw a rectangle on the image with a starting and ending corner with the specified thickness and color of the border.
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('draw-rectangle',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* startingX : starting x position of the rectangle (default 0)
|
|
||||||
* startingY : starting y position of the rectangle (default 0)
|
|
||||||
* endX : last x position of the rectangle (default "width")
|
|
||||||
* endY : last y position of the rectangle (default "height")
|
|
||||||
* thickness : thickness of the border (default 1)
|
|
||||||
* color : RGBA values separated by a space (default "0 0 0 255")
|
|
||||||
|
|
||||||
|
|
||||||
## dynamic-module
|
|
||||||
|
|
||||||
This module is used for producing each color channel based on the original image's color.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('dynamic',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* red : expression for red channel (R, G, B and A as inputs; default r)
|
|
||||||
* green : expression for green channel (R, G, B and A as inputs; default g)
|
|
||||||
* blue : expression for blue channel (R, G, B and A as inputs; default b)
|
|
||||||
* monochrome: fallback for other channels if none provided (default : r+g+b/3)
|
|
||||||
|
|
||||||
|
|
||||||
## edge-detect-module
|
|
||||||
|
|
||||||
This module is used for detecting images.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('edge-detect',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following properties:
|
|
||||||
* blur : Intensity of Gaussian blur (0 to 5; default 2)
|
|
||||||
* highThresholdRatio : Upper Threshold Ratio ( default : 0.2)
|
|
||||||
* lowThresholdratio : Lower Threshold Ratio ( default : 0.2)
|
|
||||||
|
|
||||||
|
|
||||||
## fisheyeGl-module
|
## fisheyeGl-module
|
||||||
|
|
||||||
This module is used for correcting Fisheye or Lens Distortion
|
This module is used for correcting Fisheye or Lens Distortion
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -346,12 +109,246 @@ where `options` is an object with the following properties:
|
|||||||
* x : Field of View x (0 to 2; default 1)
|
* x : Field of View x (0 to 2; default 1)
|
||||||
* y : Field of View y (0 to 2; default 1)
|
* y : Field of View y (0 to 2; default 1)
|
||||||
|
|
||||||
|
## add-qr-module
|
||||||
|
|
||||||
|
This module Adds QR corresponding to the given string.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('add-qr',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* size : size of QR code in pixels (default 200)
|
||||||
|
* qrCodeString : input string to generate QR code
|
||||||
|
|
||||||
|
|
||||||
|
## average-module
|
||||||
|
|
||||||
|
This module is used for averaging all the pixels of the image.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('average',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
## blend-module
|
||||||
|
|
||||||
|
This module is used for blending two images .
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('blend',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* offset: step of image with which current image is to be blended(Two steps back is -2, three steps back is -3 etc; default -2)
|
||||||
|
* func: function used to blend two images (default : function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] })
|
||||||
|
|
||||||
|
## blur-module
|
||||||
|
|
||||||
|
This module is used for applying a Gaussian blur effect.
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('blur',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* blur : Intensity of Gaussian blur (0 to 5; default 2)
|
||||||
|
|
||||||
|
## brightness-module
|
||||||
|
|
||||||
|
This module is used for changing the brightness of the image.
|
||||||
|
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('brightness',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* brightness : brightness of the image in percentage (0 to 100; default 100)
|
||||||
|
|
||||||
|
## channel-module
|
||||||
|
|
||||||
|
This module is used for forming a grayscale image by applying one of the three primary colors.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('channel',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* channel : color of the channel (red, green, blue; default green)
|
||||||
|
|
||||||
|
## colorbar-module
|
||||||
|
|
||||||
|
This module is used for displaying an image with a colorbar.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('colorbar',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* colormap : Name of the Colormap(default, greyscale, stretched, fastie, brntogrn, blutoredjet, colors16; default: default)
|
||||||
|
* x : X-position of the image on which the new image is overlayed (default 0)
|
||||||
|
* y : Y-position of the image on which the new image is overlayed (default 0)
|
||||||
|
* h : height of resulting cropped image (default : 50% of input image width )
|
||||||
|
|
||||||
|
## colormap-module
|
||||||
|
|
||||||
|
This module is used for mapping brightness values (average of red, green & blue) to a given color lookup table, made up of a set of one more color gradients.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('colormap',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* colormap : Name of the Colormap ( greyscale, stretched, fastie, brntogrn, blutoredjet, colors16)
|
||||||
|
|
||||||
|
## contrast-module
|
||||||
|
|
||||||
|
This module is used for changing the contrast of the image.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('contrast',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* contrast : contrast for the given image (-100 to 100; default : 70)
|
||||||
|
|
||||||
|
## convolution-module
|
||||||
|
|
||||||
|
This module is used for performing image-convolution.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('convolution',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* constantFactor : a constant factor, multiplies all the kernel values by that factor (default : 1/9)
|
||||||
|
* kernelValues : nine space separated numbers representing the kernel values in left to right and top to bottom format(default : 1 1 1 1 1 1 1 1 1)
|
||||||
|
|
||||||
|
## decodeQr-module
|
||||||
|
|
||||||
|
This module is used for decoding a QR in image (if present).
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('decode-qr',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
## dither-module
|
||||||
|
|
||||||
|
This module approximates a color from a mixture of other colors when the required color is not available, creating illusions of the color that is not present actually.
|
||||||
|
|
||||||
|
[more info on wikipedia](https://en.wikipedia.org/wiki/Dither)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('dither',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* dither : Can select the name of the Dithering Algorithm(default none)
|
||||||
|
|
||||||
|
## draw-rectangle-module
|
||||||
|
|
||||||
|
This module helps to draw a rectangle on the image with a starting and ending corner with the specified thickness and color of the border.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('draw-rectangle',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* startingX : starting x position of the rectangle (default 0)
|
||||||
|
* startingY : starting y position of the rectangle (default 0)
|
||||||
|
* endX : last x position of the rectangle (default "width")
|
||||||
|
* endY : last y position of the rectangle (default "height")
|
||||||
|
* thickness : thickness of the border (default 1)
|
||||||
|
* color : RGBA values separated by a space (default "0 0 0 255")
|
||||||
|
|
||||||
|
## dynamic-module
|
||||||
|
|
||||||
|
This module is used for producing each color channel based on the original image's color.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('dynamic',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* red : expression for red channel (R, G, B and A as inputs; default r)
|
||||||
|
* green : expression for green channel (R, G, B and A as inputs; default g)
|
||||||
|
* blue : expression for blue channel (R, G, B and A as inputs; default b)
|
||||||
|
* monochrome: fallback for other channels if none provided (default : r+g+b/3)
|
||||||
|
|
||||||
|
## edge-detect-module
|
||||||
|
|
||||||
|
This module is used for detecting images.
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('edge-detect',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following properties:
|
||||||
|
* blur : Intensity of Gaussian blur (0 to 5; default 2)
|
||||||
|
* highThresholdRatio : Upper Threshold Ratio ( default : 0.2)
|
||||||
|
* lowThresholdratio : Lower Threshold Ratio ( default : 0.2)
|
||||||
|
|
||||||
## flipimage-module
|
## flipimage-module
|
||||||
|
|
||||||
This module is used for flipping the image on the selected axis.
|
This module is used for flipping the image on the selected axis.
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
sequencer.loadImage('PATH')
|
sequencer.loadImage('PATH')
|
||||||
.addSteps('flip-image',options)
|
.addSteps('flip-image',options)
|
||||||
@@ -376,7 +373,6 @@ This module is used for applying gamma correction.
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* adjustment : Inverse of actual gamma factor (default 0.2)
|
* adjustment : Inverse of actual gamma factor (default 0.2)
|
||||||
|
|
||||||
|
|
||||||
## gradient-module
|
## gradient-module
|
||||||
|
|
||||||
This module is used for finding gradient of the image.
|
This module is used for finding gradient of the image.
|
||||||
@@ -388,23 +384,6 @@ This module is used for finding gradient of the image.
|
|||||||
.run()
|
.run()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Grid Overlay
|
|
||||||
|
|
||||||
This adds the grid over an image.
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('grid-overlay',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* options.x : The value at which the grid line should start in x-axis.
|
|
||||||
* options.y : The value at which the grid line should start in y-axis.
|
|
||||||
* color : Color for the grid on the image.
|
|
||||||
|
|
||||||
|
|
||||||
## histogram-module
|
## histogram-module
|
||||||
|
|
||||||
This module is used for calculating histogram of the image.
|
This module is used for calculating histogram of the image.
|
||||||
@@ -419,7 +398,6 @@ This module is used for calculating histogram of the image.
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* gradient : boolean value used to toggle gradient along x-axis (true or false; default true)
|
* gradient : boolean value used to toggle gradient along x-axis (true or false; default true)
|
||||||
|
|
||||||
|
|
||||||
## import-image-module
|
## import-image-module
|
||||||
|
|
||||||
This module is used for importing a new image and replacing the original with it.
|
This module is used for importing a new image and replacing the original with it.
|
||||||
@@ -434,7 +412,6 @@ This module is used for importing a new image and replacing the original with it
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* url : url of the new image (local image url or data url;default : "./images/monarch.png")
|
* url : url of the new image (local image url or data url;default : "./images/monarch.png")
|
||||||
|
|
||||||
|
|
||||||
## invert-module
|
## invert-module
|
||||||
|
|
||||||
This module is used for inverting the image.
|
This module is used for inverting the image.
|
||||||
@@ -446,21 +423,6 @@ This module is used for inverting the image.
|
|||||||
.run()
|
.run()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Minify Image
|
|
||||||
|
|
||||||
This module minifies the image using lossy compression that is the image-dimensions are not lost but the size is reduced.
|
|
||||||
|
|
||||||
The module supports jpg/jpeg/webp images in browser; but the node version supports all of the types.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('minify-image')
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## ndvi-module
|
## ndvi-module
|
||||||
|
|
||||||
This module is used for applying ndvi technique to the image.
|
This module is used for applying ndvi technique to the image.
|
||||||
@@ -475,7 +437,6 @@ This module is used for applying ndvi technique to the image.
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* filter : filter for NDVI (blue or red; default red)
|
* filter : filter for NDVI (blue or red; default red)
|
||||||
|
|
||||||
|
|
||||||
## ndvi-colormap-module
|
## ndvi-colormap-module
|
||||||
|
|
||||||
This module is used for demonstrating ndvi and colormap properties consecutively.
|
This module is used for demonstrating ndvi and colormap properties consecutively.
|
||||||
@@ -487,7 +448,6 @@ This module is used for demonstrating ndvi and colormap properties consecutively
|
|||||||
.run()
|
.run()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## overlay-module
|
## overlay-module
|
||||||
|
|
||||||
This module is used for overlaying an Image over another .
|
This module is used for overlaying an Image over another .
|
||||||
@@ -504,10 +464,10 @@ where `options` is an object with the following properties:
|
|||||||
* y : Y-position of the image on which the new image is overlayed (default 0)
|
* y : Y-position of the image on which the new image is overlayed (default 0)
|
||||||
* offset : offset to the step on which the output of the last step is overlayed (default -2)
|
* offset : offset to the step on which the output of the last step is overlayed (default -2)
|
||||||
|
|
||||||
|
|
||||||
## paint-bucket-module
|
## paint-bucket-module
|
||||||
|
|
||||||
This module fills any polygonal shape with the specified color in pixels.
|
This module fills any polygonal shape with the specified color in pixels.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -522,6 +482,19 @@ where `options` is an object with the following property:
|
|||||||
* fillColor : they are four spaced seperated numbers representing the RGBA values of fill-color (default "100 100 100 255")
|
* fillColor : they are four spaced seperated numbers representing the RGBA values of fill-color (default "100 100 100 255")
|
||||||
* tolerance : it is the % tolerance (default 10)
|
* tolerance : it is the % tolerance (default 10)
|
||||||
|
|
||||||
|
## resize-module
|
||||||
|
|
||||||
|
This module is used for resizing an image.
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('resize',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* resize : Percentage value of resize (default 125%)
|
||||||
|
|
||||||
## replacecolor-module
|
## replacecolor-module
|
||||||
|
|
||||||
@@ -539,22 +512,6 @@ where `options` is an object with the following properties:
|
|||||||
* color : three space separated numbers representing the RGB values of color to be replaced (default "228 86 81")
|
* color : three space separated numbers representing the RGB values of color to be replaced (default "228 86 81")
|
||||||
* tolerance : it is the % tolerance (default 50)
|
* tolerance : it is the % tolerance (default 50)
|
||||||
|
|
||||||
|
|
||||||
## resize-module
|
|
||||||
|
|
||||||
This module is used for resizing an image.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('resize',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the following property:
|
|
||||||
* resize : Percentage value of resize (default 125%)
|
|
||||||
|
|
||||||
|
|
||||||
## rotate-module
|
## rotate-module
|
||||||
|
|
||||||
This module is used for rotating an image.
|
This module is used for rotating an image.
|
||||||
@@ -569,7 +526,6 @@ This module is used for rotating an image.
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* rotate : angular value for rotation in degrees (between 0 and 360; default 0)
|
* rotate : angular value for rotation in degrees (between 0 and 360; default 0)
|
||||||
|
|
||||||
|
|
||||||
## saturation-module
|
## saturation-module
|
||||||
|
|
||||||
This module is used for changing the saturation of the image.
|
This module is used for changing the saturation of the image.
|
||||||
@@ -584,49 +540,11 @@ This module is used for changing the saturation of the image.
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* saturation : saturation for the new image (between 0 and 2; default 0)
|
* saturation : saturation for the new image (between 0 and 2; default 0)
|
||||||
|
|
||||||
|
|
||||||
## segmented-colormap-module
|
|
||||||
|
|
||||||
This module is used to map the pixels of the image to a segmented colormap.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('segmented-colormap',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
where `options` is an object with the property `colormap`. `options.colormap` can be:
|
|
||||||
|
|
||||||
* "default" : [[0, [0, 0, 255], [38, 195, 195]], [0.5, [0, 150, 0], [255, 255, 0]], [0.75, [255, 255, 0], [255, 50, 50]]]
|
|
||||||
|
|
||||||
* "greyscale" : [[0, [0, 0, 0], [255, 255, 255]], [1, [255, 255, 255], [255, 255, 255]]]
|
|
||||||
|
|
||||||
* "stretched" : [[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" : [[0, [255, 255, 255], [0, 0, 0]], [0.167, [0, 0, 0], [255, 255, 255]], [0.33, [255, 255, 255], [0, 0, 0]], [0.5, [0, 0, 0], [140, 140, 255]], [0.55, [140, 140, 255], [0, 255, 0]], [0.63, [0, 255, 0], [255, 255, 0]], [0.75, [255, 255, 0], [255, 0, 0]], [0.95, [255, 0, 0], [255, 0, 255]]]
|
|
||||||
|
|
||||||
* A custom array.
|
|
||||||
|
|
||||||
|
|
||||||
## Text Overlay
|
|
||||||
|
|
||||||
The modules allows to add text to image in both browser and node environment. We have the options to modify the font-size and also support few font-styles. The text color can also be modified.
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
sequencer.loadImage('PATH')
|
|
||||||
.addSteps('grid-overlay',options)
|
|
||||||
.run()
|
|
||||||
```
|
|
||||||
The options can take various attributes like,
|
|
||||||
var options = { text : 'Hello World', size : '12'};
|
|
||||||
|
|
||||||
|
|
||||||
## Threshold
|
## Threshold
|
||||||
|
|
||||||
Thresholding is used to create binary images.
|
Thresholding is used to create binary images.
|
||||||
#### Usage
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
sequencer.loadImage('PATH')
|
sequencer.loadImage('PATH')
|
||||||
@@ -641,7 +559,8 @@ where `options` is an object with the following property:
|
|||||||
## Tint
|
## Tint
|
||||||
|
|
||||||
It adds color tint to an image
|
It adds color tint to an image
|
||||||
#### Usage
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
sequencer.loadImage('PATH')
|
sequencer.loadImage('PATH')
|
||||||
@@ -651,3 +570,34 @@ It adds color tint to an image
|
|||||||
where `options` is an object with the following property:
|
where `options` is an object with the following property:
|
||||||
* color : RGB values seperated by a space (default "0 0 255")
|
* color : RGB values seperated by a space (default "0 0 255")
|
||||||
* factor : amount of tint (default 0.5)
|
* factor : amount of tint (default 0.5)
|
||||||
|
|
||||||
|
|
||||||
|
## Color Temperature
|
||||||
|
|
||||||
|
This changes the color temperature of the image.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('color-temperature',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* temperature : temperature between 0 - 40,000 kelvin (default 6000)
|
||||||
|
|
||||||
|
## Grid Overlay
|
||||||
|
|
||||||
|
This adds the grid over an image.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
sequencer.loadImage('PATH')
|
||||||
|
.addSteps('grid-overlay',options)
|
||||||
|
.run()
|
||||||
|
```
|
||||||
|
where `options` is an object with the following property:
|
||||||
|
* options.x : The value at which the grid line should start in x-axis.
|
||||||
|
* options.y : The value at which the grid line should start in y-axis.
|
||||||
|
* color : Color for the grid on the image.
|
||||||
@@ -272,7 +272,3 @@ a.name-header{
|
|||||||
align:center;
|
align:center;
|
||||||
width:100%;
|
width:100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ window.onload = function() {
|
|||||||
// Load information of all modules (Name, Inputs, Outputs)
|
// Load information of all modules (Name, Inputs, Outputs)
|
||||||
var modulesInfo = sequencer.modulesInfo();
|
var modulesInfo = sequencer.modulesInfo();
|
||||||
|
|
||||||
var addStepSelect = $('#addStep select');
|
var addStepSelect = $("#addStep select");
|
||||||
addStepSelect.html('');
|
addStepSelect.html("");
|
||||||
|
|
||||||
// Add modules to the addStep dropdown
|
// Add modules to the addStep dropdown
|
||||||
for (var m in modulesInfo) {
|
for (var m in modulesInfo) {
|
||||||
if (modulesInfo[m] && modulesInfo[m].name)
|
if (modulesInfo[m] && modulesInfo[m].name)
|
||||||
addStepSelect.append(
|
addStepSelect.append(
|
||||||
'<option value="' + m + '">' + modulesInfo[m].name + '</option>'
|
'<option value="' + m + '">' + modulesInfo[m].name + "</option>"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Null option
|
// Null option
|
||||||
@@ -46,7 +46,7 @@ window.onload = function() {
|
|||||||
$(':root').animate({scrollTop: 0});
|
$(':root').animate({scrollTop: 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#move-up').on('click', topFunction);
|
$('#move-up').on("click",topFunction);
|
||||||
|
|
||||||
|
|
||||||
// UI for each step:
|
// UI for each step:
|
||||||
@@ -59,43 +59,48 @@ window.onload = function() {
|
|||||||
if (urlHash.getUrlHashParameter('src')) {
|
if (urlHash.getUrlHashParameter('src')) {
|
||||||
sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad);
|
sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad);
|
||||||
} else {
|
} else {
|
||||||
sequencer.loadImage('images/tulips.png', ui.onLoad);
|
sequencer.loadImage("images/tulips.png", ui.onLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
var resetSequence = function(){
|
var resetSequence = function(){
|
||||||
var r = confirm('Do you want to reset the sequence?');
|
var r=confirm("Do you want to reset the sequence?");
|
||||||
if (r)
|
if (r)
|
||||||
window.location = '/';
|
window.location = "/";
|
||||||
};
|
}
|
||||||
|
|
||||||
$('#addStep select').on('change', ui.selectNewStepUi);
|
$("#addStep select").on("change", ui.selectNewStepUi);
|
||||||
$('#addStep #add-step-btn').on('click', ui.addStepUi);
|
$("#addStep #add-step-btn").on("click", ui.addStepUi);
|
||||||
$('#resetButton').on('click', resetSequence);
|
$("#resetButton").on("click",resetSequence);
|
||||||
|
|
||||||
//Module button radio selection
|
//Module button radio selection
|
||||||
$('.radio-group .radio').on('click', function() {
|
$('.radio-group .radio').on("click", function() {
|
||||||
$(this).parent().find('.radio').removeClass('selected');
|
$(this).parent().find('.radio').removeClass('selected');
|
||||||
$(this).addClass('selected');
|
$(this).addClass('selected');
|
||||||
newStep = $(this).attr('data-value');
|
newStep = $(this).attr('data-value');
|
||||||
//$("#addStep option[value=" + newStep + "]").attr('selected', 'selected');
|
//$("#addStep option[value=" + newStep + "]").attr('selected', 'selected');
|
||||||
$('#addStep select').val(newStep);
|
$("#addStep select").val(newStep);
|
||||||
ui.selectNewStepUi(newStep);
|
ui.selectNewStepUi(newStep);
|
||||||
ui.addStepUi(newStep);
|
ui.addStepUi(newStep);
|
||||||
$(this).removeClass('selected');
|
$(this).removeClass('selected');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#download-btn').click(function() {
|
||||||
|
$('.step-thumbnail:last()').trigger("click");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
function displayMessageOnSaveSequence(){
|
function displayMessageOnSaveSequence(){
|
||||||
$('.savesequencemsg').fadeIn();
|
$(".savesequencemsg").fadeIn();
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$('.savesequencemsg').fadeOut();
|
$(".savesequencemsg").fadeOut();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('body').on('click', 'button.remove', ui.removeStepUi);
|
$('body').on('click', 'button.remove', ui.removeStepUi);
|
||||||
$('#save-seq').click(() => {
|
$('#save-seq').click(() => {
|
||||||
var result = window.prompt('Please give a name to your sequence... (Saved sequence will only be available in this browser).');
|
var result = window.prompt("Please give a name to your sequence... (Saved sequence will only be available in this browser).");
|
||||||
if(result){
|
if(result){
|
||||||
result = result + ' (local)';
|
result = result + " (local)";
|
||||||
sequencer.saveSequence(result, sequencer.toString());
|
sequencer.saveSequence(result, sequencer.toString());
|
||||||
sequencer.loadModules();
|
sequencer.loadModules();
|
||||||
displayMessageOnSaveSequence();
|
displayMessageOnSaveSequence();
|
||||||
@@ -113,11 +118,11 @@ window.onload = function() {
|
|||||||
|
|
||||||
var button = event.target;
|
var button = event.target;
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
button.innerHTML = '<i class="fa fa-circle-o-notch fa-spin"></i>';
|
button.innerHTML='<i class="fa fa-circle-o-notch fa-spin"></i>'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Select all images from previous steps
|
// Select all images from previous steps
|
||||||
var imgs = document.getElementsByClassName('step-thumbnail');
|
var imgs = document.getElementsByClassName("step-thumbnail");
|
||||||
|
|
||||||
var imgSrcs = [];
|
var imgSrcs = [];
|
||||||
|
|
||||||
@@ -130,7 +135,7 @@ window.onload = function() {
|
|||||||
'gifHeight': imgs[0].height,
|
'gifHeight': imgs[0].height,
|
||||||
'images': imgSrcs,
|
'images': imgSrcs,
|
||||||
'frameDuration': 7,
|
'frameDuration': 7,
|
||||||
};
|
}
|
||||||
|
|
||||||
gifshot.createGIF(options, function(obj) {
|
gifshot.createGIF(options, function(obj) {
|
||||||
if (!obj.error) {
|
if (!obj.error) {
|
||||||
@@ -138,21 +143,21 @@ window.onload = function() {
|
|||||||
var image = obj.image;
|
var image = obj.image;
|
||||||
var animatedImage = document.createElement('img');
|
var animatedImage = document.createElement('img');
|
||||||
|
|
||||||
animatedImage.id = 'gif_element';
|
animatedImage.id = "gif_element";
|
||||||
animatedImage.src = image;
|
animatedImage.src = image;
|
||||||
|
|
||||||
|
|
||||||
var modal = $('#js-download-gif-modal');
|
var modal = $('#js-download-gif-modal');
|
||||||
|
|
||||||
$('#js-download-as-gif-button').one('click', function() {
|
$("#js-download-as-gif-button").one("click", function() {
|
||||||
// Trigger download
|
// Trigger download
|
||||||
download(image, 'index.gif', 'image/gif');
|
download(image, "index.gif", "image/gif");
|
||||||
|
|
||||||
// Close modal
|
// Close modal
|
||||||
modal.modal('hide');
|
modal.modal('hide');
|
||||||
});
|
})
|
||||||
|
|
||||||
var gifContainer = document.getElementById('js-download-modal-gif-container');
|
var gifContainer = document.getElementById("js-download-modal-gif-container");
|
||||||
|
|
||||||
// Clear previous results
|
// Clear previous results
|
||||||
gifContainer.innerHTML = '';
|
gifContainer.innerHTML = '';
|
||||||
@@ -181,16 +186,16 @@ window.onload = function() {
|
|||||||
|
|
||||||
// image selection and drag/drop handling from examples/lib/imageSelection.js
|
// image selection and drag/drop handling from examples/lib/imageSelection.js
|
||||||
sequencer.setInputStep({
|
sequencer.setInputStep({
|
||||||
dropZoneSelector: '#dropzone',
|
dropZoneSelector: "#dropzone",
|
||||||
fileInputSelector: '#fileInput',
|
fileInputSelector: "#fileInput",
|
||||||
takePhotoSelector: '#take-photo',
|
takePhotoSelector: "#take-photo",
|
||||||
onLoad: function onFileReaderLoad(progress) {
|
onLoad: function onFileReaderLoad(progress) {
|
||||||
var reader = progress.target;
|
var reader = progress.target;
|
||||||
var step = sequencer.steps[0];
|
var step = sequencer.steps[0];
|
||||||
var util= intermediateHtmlStepUi(sequencer);
|
var util= intermediateHtmlStepUi(sequencer);
|
||||||
step.output.src = reader.result;
|
step.output.src = reader.result;
|
||||||
sequencer.run({ index: 0 });
|
sequencer.run({ index: 0 });
|
||||||
if(typeof step.options !== 'undefined')
|
if(typeof step.options !=="undefined")
|
||||||
step.options.step.imgElement.src = reader.result;
|
step.options.step.imgElement.src = reader.result;
|
||||||
else
|
else
|
||||||
step.imgElement.src = reader.result;
|
step.imgElement.src = reader.result;
|
||||||
@@ -201,7 +206,7 @@ window.onload = function() {
|
|||||||
var step = sequencer.steps[0];
|
var step = sequencer.steps[0];
|
||||||
step.output.src = url;
|
step.output.src = url;
|
||||||
sequencer.run({ index: 0 });
|
sequencer.run({ index: 0 });
|
||||||
if(typeof step.options !== 'undefined')
|
if(typeof step.options !=="undefined")
|
||||||
step.options.step.imgElement.src = url;
|
step.options.step.imgElement.src = url;
|
||||||
else
|
else
|
||||||
step.imgElement.src = url;
|
step.imgElement.src = url;
|
||||||
@@ -215,6 +220,6 @@ window.onload = function() {
|
|||||||
if (urlHash.getUrlHashParameter('src')) {
|
if (urlHash.getUrlHashParameter('src')) {
|
||||||
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'),'#addStep');
|
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'),'#addStep');
|
||||||
} else {
|
} else {
|
||||||
insertPreview.updatePreviews('images/tulips.png', '#addStep');
|
insertPreview.updatePreviews("images/tulips.png",'#addStep');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -9,16 +9,11 @@
|
|||||||
<meta name="theme-color" content="#428bca">
|
<meta name="theme-color" content="#428bca">
|
||||||
<link rel="icon" sizes="192x192" href="../icons/ic_192.png">
|
<link rel="icon" sizes="192x192" href="../icons/ic_192.png">
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
|
|
||||||
<!--Adding meta Tag for search engine optimisation-->
|
<!--Adding meta Tag for search engine optimisation-->
|
||||||
<meta property="og:description"
|
<meta property="og:description" content="A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original image, it creates a new image at each step in a sequence.">
|
||||||
content="A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original image, it creates a new image at each step in a sequence.">
|
|
||||||
<meta property="og:site_name" content="sequencer.publiclab.org">
|
<meta property="og:site_name" content="sequencer.publiclab.org">
|
||||||
<meta property="og:url" content="https://sequencer.publiclab.org">
|
<meta property="og:url" content="https://sequencer.publiclab.org">
|
||||||
<meta property="og:title" content="Image Sequencer">
|
<meta property="og:title" content="Image Sequencer">
|
||||||
<meta name="Description"
|
|
||||||
content="Image Sequencer is an image editing tool that creates a new downloadble image at each step.It works in browser and supports both node and CLI.">
|
|
||||||
<meta name="Keywords" content="image editing downloadable browser node CLI">
|
|
||||||
|
|
||||||
<title>Image Sequencer</title>
|
<title>Image Sequencer</title>
|
||||||
|
|
||||||
@@ -27,7 +22,6 @@
|
|||||||
<script src="../src/ui/prepareDynamic.js"></script>
|
<script src="../src/ui/prepareDynamic.js"></script>
|
||||||
<script src="../dist/image-sequencer.js" charset="utf-8"></script>
|
<script src="../dist/image-sequencer.js" charset="utf-8"></script>
|
||||||
<script src="../dist/image-sequencer-ui.js" charset="utf-8"></script>
|
<script src="../dist/image-sequencer-ui.js" charset="utf-8"></script>
|
||||||
<script src="../node_modules/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js"></script>
|
|
||||||
<!-- for crop module: -->
|
<!-- for crop module: -->
|
||||||
<script src="../node_modules/imgareaselect/jquery.imgareaselect.dev.js"></script>
|
<script src="../node_modules/imgareaselect/jquery.imgareaselect.dev.js"></script>
|
||||||
<script src="../node_modules/gifshot/dist/gifshot.min.js" type="text/javascript"></script>
|
<script src="../node_modules/gifshot/dist/gifshot.min.js" type="text/javascript"></script>
|
||||||
@@ -42,14 +36,10 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="../node_modules/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
<link rel="stylesheet" href="demo.css">
|
||||||
<link href="../node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet">
|
<link href="../node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet">
|
||||||
<link href="../node_modules/selectize/dist/css/selectize.default.css" rel="stylesheet">
|
<link href="../node_modules/selectize/dist/css/selectize.default.css" rel="stylesheet">
|
||||||
<!-- for crop module: -->
|
<!-- for crop module: -->
|
||||||
<!-- for crop module: -->
|
|
||||||
<link href="../node_modules/imgareaselect/distfiles/css/imgareaselect-default.css" rel="stylesheet">
|
|
||||||
<link href="./selectize.default.css" rel="stylesheet">
|
<link href="./selectize.default.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="demo.css">
|
<link rel="stylesheet" href="demo.css">
|
||||||
|
|
||||||
@@ -58,8 +48,7 @@
|
|||||||
<header class="text-center">
|
<header class="text-center">
|
||||||
<h1><a href="/" target='_blank' class="name-header">Image Sequencer</a></h1>
|
<h1><a href="/" target='_blank' class="name-header">Image Sequencer</a></h1>
|
||||||
<p>
|
<p>
|
||||||
A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original
|
A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original image, it
|
||||||
image, it
|
|
||||||
creates a new image at each step in a sequence.
|
creates a new image at each step in a sequence.
|
||||||
<a href="https://publiclab.org/image-sequencer">Learn more</a>
|
<a href="https://publiclab.org/image-sequencer">Learn more</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -79,7 +68,7 @@
|
|||||||
<center>
|
<center>
|
||||||
<input type="file" id="fileInput" value="" accept="image/*"><br />
|
<input type="file" id="fileInput" value="" accept="image/*"><br />
|
||||||
<button type="button" id="take-photo" class="btn btn-primary btn-block btn-lg ">Take a Photo</button>
|
<button type="button" id="take-photo" class="btn btn-primary btn-block btn-lg ">Take a Photo</button>
|
||||||
<video id="video" width="100%" height="100%" style="display:none"></video>
|
<video id="video" width="400" height="300" style="display:none"></video>
|
||||||
<a href="#" id="capture" style="display:none" class="btn btn-primary btn-md">Click Picture</a>
|
<a href="#" id="capture" style="display:none" class="btn btn-primary btn-md">Click Picture</a>
|
||||||
<a href="#" id="close" style="display:none" class="btn btn-default btn-md">Close</a>
|
<a href="#" id="close" style="display:none" class="btn btn-default btn-md">Close</a>
|
||||||
<canvas id="canvas" width="400" height="300" style="display:none"></canvas>
|
<canvas id="canvas" width="400" height="300" style="display:none"></canvas>
|
||||||
@@ -91,8 +80,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<p class="alert alert-success savesequencemsg">Saved Sequence Success. Sequence can be found among other modules.
|
<p class = "alert alert-success savesequencemsg">Saved Sequence Success. Sequence can be found among other modules.</p>
|
||||||
</p>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<section id="addStep" class="panel panel-primary">
|
<section id="addStep" class="panel panel-primary">
|
||||||
@@ -151,8 +139,7 @@
|
|||||||
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button></div>
|
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center-align">
|
<div class="row center-align">
|
||||||
<button id="resetButton" class="btn btn-default btn-lg"
|
<button id="resetButton" class="btn btn-default btn-lg" style=" margin: 20px 35px 0px 35px; width:100%;">Clear All Steps</button>
|
||||||
style=" margin: 20px 35px 0px 35px; width:100%;">Clear All Steps</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,8 +149,7 @@
|
|||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
aria-hidden="true">×</span></button>
|
|
||||||
<h4 class="modal-title">Your gif is ready</h4>
|
<h4 class="modal-title">Your gif is ready</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
@@ -203,8 +189,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<hr style="margin:20px;">
|
<hr style="margin:20px;"><center><button class="btn btn-default btn-sm" id="clear-cache">Clear offline cache</button></center>
|
||||||
<center><button class="btn btn-default btn-sm" id="clear-cache">Clear offline cache</button></center>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2>Need Help?</h2>
|
<h2>Need Help?</h2>
|
||||||
@@ -232,7 +217,6 @@
|
|||||||
var sequencer;
|
var sequencer;
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<script async src="../node_modules/opencv.js/opencv.js" type="text/javascript"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ var setupCache = function() {
|
|||||||
.then(function(registration) {
|
.then(function(registration) {
|
||||||
const installingWorker = registration.installing;
|
const installingWorker = registration.installing;
|
||||||
installingWorker.onstatechange = () => {
|
installingWorker.onstatechange = () => {
|
||||||
console.log(installingWorker);
|
console.log(installingWorker)
|
||||||
if (installingWorker.state === 'installed') {
|
if (installingWorker.state === 'installed') {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
console.log('Registration successful, scope is:', registration.scope);
|
console.log('Registration successful, scope is:', registration.scope);
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
@@ -19,12 +19,12 @@ var setupCache = function() {
|
|||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
caches.keys().then(function(cacheNames) {
|
caches.keys().then(function(cacheNames) {
|
||||||
cacheNames.forEach(function(cacheName) {
|
cacheNames.forEach(function(cacheName) {
|
||||||
$('#clear-cache').append(' ' + cacheName);
|
$("#clear-cache").append(" " + cacheName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#clear-cache').click(function() {
|
$("#clear-cache").click(function() {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
caches.keys().then(function(cacheNames) {
|
caches.keys().then(function(cacheNames) {
|
||||||
cacheNames.forEach(function(cacheName) {
|
cacheNames.forEach(function(cacheName) {
|
||||||
@@ -34,6 +34,6 @@ var setupCache = function() {
|
|||||||
}
|
}
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = setupCache;
|
module.exports = setupCache;
|
||||||
|
|||||||
@@ -2,51 +2,50 @@ var urlHash = require('./urlHash.js');
|
|||||||
function DefaultHtmlSequencerUi(_sequencer, options) {
|
function DefaultHtmlSequencerUi(_sequencer, options) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var addStepSel = options.addStepSel = options.addStepSel || '#addStep';
|
var addStepSel = options.addStepSel = options.addStepSel || "#addStep";
|
||||||
var removeStepSel = options.removeStepSel = options.removeStepSel || 'button.remove';
|
var removeStepSel = options.removeStepSel = options.removeStepSel || "button.remove";
|
||||||
var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep';
|
var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep";
|
||||||
|
|
||||||
function onLoad() {
|
function onLoad() {
|
||||||
importStepsFromUrlHash();
|
importStepsFromUrlHash();
|
||||||
if ($('#selectStep').val()==='none')
|
if ($('#selectStep').val()==='none')
|
||||||
$(addStepSel + ' #add-step-btn').prop('disabled', true);
|
$(addStepSel + " #add-step-btn").prop("disabled", true);
|
||||||
handleSaveSequence();
|
handleSaveSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up needed steps from Url Hash:
|
// look up needed steps from Url Hash:
|
||||||
function importStepsFromUrlHash() {
|
function importStepsFromUrlHash() {
|
||||||
var hash = urlHash.getUrlHashParameter('steps');
|
var hash = urlHash.getUrlHashParameter("steps");
|
||||||
|
|
||||||
if (hash) {
|
if (hash) {
|
||||||
_sequencer.importString(hash);
|
_sequencer.importString(hash);
|
||||||
_sequencer.run({ index: 0 });
|
_sequencer.run({ index: 0 });
|
||||||
}
|
}
|
||||||
urlHash.setUrlHashParameter('steps', sequencer.toString());
|
urlHash.setUrlHashParameter("steps", sequencer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNewStepUi() {
|
function selectNewStepUi() {
|
||||||
var m = $(addStepSel + ' select').val();
|
var m = $(addStepSel + " select").val();
|
||||||
if(!m) m = arguments[0];
|
if(!m) m = arguments[0];
|
||||||
$(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description);
|
$(addStepSel + " .info").html(_sequencer.modulesInfo(m).description);
|
||||||
$(addStepSel + ' #add-step-btn').prop('disabled', false);
|
$(addStepSel + " #add-step-btn").prop("disabled", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeStepUi() {
|
function removeStepUi() {
|
||||||
var index = $(removeStepSel).index(this) + 1;
|
var index = $(removeStepSel).index(this) + 1;
|
||||||
sequencer.removeSteps(index).run({ index: index - 1 });
|
sequencer.removeSteps(index).run({ index: index - 1 });
|
||||||
// remove from URL hash too
|
// remove from URL hash too
|
||||||
urlHash.setUrlHashParameter('steps', sequencer.toString());
|
urlHash.setUrlHashParameter("steps", sequencer.toString());
|
||||||
//disable save-sequence button if all steps are removed
|
//disable save-sequence button if all steps are removed
|
||||||
handleSaveSequence();
|
handleSaveSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStepUi() {
|
function addStepUi() {
|
||||||
if ($(addStepSel + ' select').val() == 'none') return;
|
if ($(addStepSel + " select").val() == "none") return;
|
||||||
var newStepName;
|
|
||||||
if(typeof arguments[0] !== 'string')
|
|
||||||
newStepName = $(addStepSel + ' select option').html().toLowerCase().split(' ').join('-');
|
|
||||||
else newStepName = arguments[0];
|
|
||||||
|
|
||||||
|
var newStepName = $(addStepSel + " select").val();
|
||||||
|
|
||||||
|
if(!newStepName) newStepName = arguments[0]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* after adding the step we run the sequencer from defined step
|
* after adding the step we run the sequencer from defined step
|
||||||
@@ -56,28 +55,28 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
|
|||||||
var sequenceLength = 1;
|
var sequenceLength = 1;
|
||||||
if (sequencer.sequences[newStepName]) {
|
if (sequencer.sequences[newStepName]) {
|
||||||
sequenceLength = sequencer.sequences[newStepName].length;
|
sequenceLength = sequencer.sequences[newStepName].length;
|
||||||
} else if (sequencer.modules[newStepName][1]['length']) {
|
} else if (sequencer.modules[newStepName][1]["length"]) {
|
||||||
sequenceLength = sequencer.modules[newStepName][1]['length'];
|
sequenceLength = sequencer.modules[newStepName][1]["length"];
|
||||||
}
|
}
|
||||||
_sequencer
|
_sequencer
|
||||||
.addSteps(newStepName, options)
|
.addSteps(newStepName, options)
|
||||||
.run({ index: _sequencer.steps.length - sequenceLength - 1 });
|
.run({ index: _sequencer.steps.length - sequenceLength - 1 });
|
||||||
$(addStepSel + ' .info').html('Select a new module to add to your sequence.');
|
$(addStepSel + " .info").html("Select a new module to add to your sequence.");
|
||||||
$(addStepSel + ' select').val('none');
|
$(addStepSel + " select").val("none");
|
||||||
|
|
||||||
//enable save-sequence button if disabled initially
|
//enable save-sequence button if disabled initially
|
||||||
handleSaveSequence();
|
handleSaveSequence();
|
||||||
|
|
||||||
// add to URL hash too
|
// add to URL hash too
|
||||||
urlHash.setUrlHashParameter('steps', _sequencer.toString());
|
urlHash.setUrlHashParameter("steps", _sequencer.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSaveSequence(){
|
function handleSaveSequence(){
|
||||||
var stepCount=sequencer.steps.length;
|
var stepCount=sequencer.steps.length;
|
||||||
if(stepCount<2)
|
if(stepCount<2)
|
||||||
$(' #save-seq').prop('disabled', true);
|
$(" #save-seq").prop("disabled", true);
|
||||||
else
|
else
|
||||||
$(' #save-seq').prop('disabled', false);
|
$(" #save-seq").prop("disabled", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -86,7 +85,7 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
|
|||||||
selectNewStepUi: selectNewStepUi,
|
selectNewStepUi: selectNewStepUi,
|
||||||
removeStepUi: removeStepUi,
|
removeStepUi: removeStepUi,
|
||||||
addStepUi: addStepUi
|
addStepUi: addStepUi
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DefaultHtmlSequencerUi;
|
module.exports = DefaultHtmlSequencerUi;
|
||||||
|
|||||||
@@ -8,21 +8,18 @@
|
|||||||
// output values, step information.
|
// output values, step information.
|
||||||
// See documetation for more details.
|
// See documetation for more details.
|
||||||
|
|
||||||
const intermediateHtmlStepUi = require('./intermediateHtmlStepUi.js'),
|
var intermediateHtmlStepUi = require('./intermediateHtmlStepUi.js');
|
||||||
urlHash = require('./urlHash.js'),
|
var urlHash = require('./urlHash.js');
|
||||||
_ = require('lodash'),
|
var _ = require('lodash');
|
||||||
mapHtmlTypes = require('./mapHtmltypes'),
|
var mapHtmlTypes = require('./mapHtmltypes');
|
||||||
scopeQuery = require('./scopeQuery');
|
|
||||||
|
|
||||||
function DefaultHtmlStepUi(_sequencer, options) {
|
function DefaultHtmlStepUi(_sequencer, options) {
|
||||||
let $step, $stepAll;
|
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var stepsEl = options.stepsEl || document.querySelector('#steps');
|
var stepsEl = options.stepsEl || document.querySelector("#steps");
|
||||||
var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep';
|
var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep";
|
||||||
|
|
||||||
function onSetup(step, stepOptions) {
|
function onSetup(step, stepOptions) {
|
||||||
|
|
||||||
if (step.options && step.options.description)
|
if (step.options && step.options.description)
|
||||||
step.description = step.options.description;
|
step.description = step.options.description;
|
||||||
|
|
||||||
@@ -42,7 +39,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
<div class="row step">\
|
<div class="row step">\
|
||||||
<div class="col-md-4 details container-fluid">\
|
<div class="col-md-4 details container-fluid">\
|
||||||
<div class="cal collapse in"><p>' +
|
<div class="cal collapse in"><p>' +
|
||||||
'<i>' + (step.description || '') + '</i>' +
|
'<i>' + (step.description || "") + '</i>' +
|
||||||
'</p></div>\
|
'</p></div>\
|
||||||
</div>\
|
</div>\
|
||||||
<div class="col-md-8 cal collapse in step-column">\
|
<div class="col-md-8 cal collapse in step-column">\
|
||||||
@@ -68,16 +65,10 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
var util = intermediateHtmlStepUi(_sequencer, step);
|
var util = intermediateHtmlStepUi(_sequencer, step);
|
||||||
|
|
||||||
var parser = new DOMParser();
|
var parser = new DOMParser();
|
||||||
step.ui = parser.parseFromString(step.ui, 'text/html');
|
step.ui = parser.parseFromString(step.ui, "text/html");
|
||||||
step.ui = step.ui.querySelector('div.container-fluid');
|
step.ui = step.ui.querySelector("div.container-fluid");
|
||||||
|
step.linkElements = step.ui.querySelectorAll("a");
|
||||||
$step = scopeQuery.scopeSelector(step.ui);
|
step.imgElement = step.ui.querySelector("a img.img-thumbnail");
|
||||||
$stepAll = scopeQuery.scopeSelectorAll(step.ui);
|
|
||||||
step.ui.$step = $step;
|
|
||||||
step.ui.$stepAll = $stepAll;
|
|
||||||
|
|
||||||
step.linkElements = step.ui.querySelectorAll('a');
|
|
||||||
step.imgElement = $step('a img.img-thumbnail')[0];
|
|
||||||
|
|
||||||
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
|
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
|
||||||
var inputs = _sequencer.modulesInfo(step.name).inputs;
|
var inputs = _sequencer.modulesInfo(step.name).inputs;
|
||||||
@@ -86,34 +77,18 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
|
|
||||||
for (var paramName in merged) {
|
for (var paramName in merged) {
|
||||||
var isInput = inputs.hasOwnProperty(paramName);
|
var isInput = inputs.hasOwnProperty(paramName);
|
||||||
var html = '';
|
var html = "";
|
||||||
var inputDesc = isInput ? mapHtmlTypes(inputs[paramName]) : {};
|
var inputDesc = isInput ? mapHtmlTypes(inputs[paramName]) : {};
|
||||||
if (!isInput) {
|
if (!isInput) {
|
||||||
html += '<span class="output"></span>';
|
html += '<span class="output"></span>';
|
||||||
}
|
} else if (inputDesc.type.toLowerCase() == "select") {
|
||||||
else if (inputDesc.type.toLowerCase() == 'select') {
|
|
||||||
|
|
||||||
html += '<select class="form-control target" name="' + paramName + '">';
|
html += '<select class="form-control target" name="' + paramName + '">';
|
||||||
for (var option in inputDesc.values) {
|
for (var option in inputDesc.values) {
|
||||||
html += '<option>' + inputDesc.values[option] + '</option>';
|
html += "<option>" + inputDesc.values[option] + "</option>";
|
||||||
}
|
}
|
||||||
html += '</select>';
|
html += "</select>";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
let paramVal = step.options[paramName] || inputDesc.default;
|
let paramVal = step.options[paramName] || inputDesc.default;
|
||||||
|
|
||||||
if (inputDesc.id == 'color-picker') { // separate input field for color-picker
|
|
||||||
html +=
|
|
||||||
'<div id="color-picker" class="input-group colorpicker-component">' +
|
|
||||||
'<input class="form-control target" type="' +
|
|
||||||
inputDesc.type +
|
|
||||||
'" name="' +
|
|
||||||
paramName +
|
|
||||||
'" value="' +
|
|
||||||
paramVal + '">' + '<span class="input-group-addon"><i></i></span>' +
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
else { // use this if the the field isn't color-picker
|
|
||||||
html =
|
html =
|
||||||
'<input class="form-control target" type="' +
|
'<input class="form-control target" type="' +
|
||||||
inputDesc.type +
|
inputDesc.type +
|
||||||
@@ -122,9 +97,9 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
'" value="' +
|
'" value="' +
|
||||||
paramVal +
|
paramVal +
|
||||||
'" placeholder ="' +
|
'" placeholder ="' +
|
||||||
(inputDesc.placeholder || '');
|
(inputDesc.placeholder || "");
|
||||||
|
|
||||||
if (inputDesc.type.toLowerCase() == 'range') {
|
if (inputDesc.type.toLowerCase() == "range") {
|
||||||
html +=
|
html +=
|
||||||
'"min="' +
|
'"min="' +
|
||||||
inputDesc.min +
|
inputDesc.min +
|
||||||
@@ -136,84 +111,79 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
}
|
}
|
||||||
else html += '">';
|
else html += '">';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
var div = document.createElement("div");
|
||||||
div.className = 'row';
|
div.className = "row";
|
||||||
div.setAttribute('name', paramName);
|
div.setAttribute("name", paramName);
|
||||||
var description = inputs[paramName].desc || paramName;
|
var description = inputs[paramName].desc || paramName;
|
||||||
div.innerHTML =
|
div.innerHTML =
|
||||||
'<div class=\'det cal collapse in\'>\
|
"<div class='det cal collapse in'>\
|
||||||
<label for=\'' +
|
<label for='" +
|
||||||
paramName +
|
paramName +
|
||||||
'\'>' +
|
"'>" +
|
||||||
description +
|
description +
|
||||||
'</label>\
|
"</label>\
|
||||||
' +
|
" +
|
||||||
html +
|
html +
|
||||||
'\
|
"\
|
||||||
</div>';
|
</div>";
|
||||||
$step('div.details').append(div);
|
step.ui.querySelector("div.details").appendChild(div);
|
||||||
}
|
}
|
||||||
$step('div.panel-footer').append(
|
$(step.ui.querySelector("div.panel-footer")).append(
|
||||||
'<div class="cal collapse in"><button type="submit" class="btn btn-sm btn-default btn-save" disabled = "true" >Apply</button> <small style="padding-top:2px;">Press apply to see changes</small></div>'
|
'<div class="cal collapse in"><button type="submit" class="btn btn-sm btn-default btn-save" disabled = "true" >Apply</button> <small style="padding-top:2px;">Press apply to see changes</small></div>'
|
||||||
);
|
);
|
||||||
$step('div.panel-footer').prepend(
|
$(step.ui.querySelector("div.panel-footer")).prepend(
|
||||||
'<button class="pull-right btn btn-default btn-sm insert-step" >\
|
'<button class="pull-right btn btn-default btn-sm insert-step" >\
|
||||||
<span class="insert-text"><i class="fa fa-plus"></i> Insert Step</span><span class="no-insert-text" style="display:none">Close</span></button>\
|
<span class="insert-text"><i class="fa fa-plus"></i> Insert Step</span><span class="no-insert-text" style="display:none">Close</span>\
|
||||||
<button class="pull-right btn btn-default btn-sm download-btn" style="margin-right:2px" >\
|
|
||||||
<i class="fa fa-download"></i>\
|
|
||||||
</button>'
|
</button>'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step.name != 'load-image') {
|
if (step.name != "load-image") {
|
||||||
$step('div.trash-container')
|
step.ui
|
||||||
|
.querySelector("div.trash-container")
|
||||||
.prepend(
|
.prepend(
|
||||||
parser.parseFromString(tools, 'text/html').querySelector('div')
|
parser.parseFromString(tools, "text/html").querySelector("div")
|
||||||
);
|
);
|
||||||
|
$(step.ui.querySelectorAll(".remove")).on('click', function() {notify('Step Removed','remove-notification')});
|
||||||
$stepAll('.remove').on('click', function() {notify('Step Removed', 'remove-notification');});
|
$(step.ui.querySelectorAll(".insert-step")).on('click', function() { util.insertStep(step.ID) });
|
||||||
$stepAll('.insert-step').on('click', function() { util.insertStep(step.ID); });
|
|
||||||
// Insert the step's UI in the right place
|
// Insert the step's UI in the right place
|
||||||
if (stepOptions.index == _sequencer.steps.length) {
|
if (stepOptions.index == _sequencer.steps.length) {
|
||||||
stepsEl.appendChild(step.ui);
|
stepsEl.appendChild(step.ui);
|
||||||
$('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true);
|
$("#steps .step-container:nth-last-child(1) .insert-step").prop('disabled',true);
|
||||||
if($('#steps .step-container:nth-last-child(2)'))
|
if($("#steps .step-container:nth-last-child(2)"))
|
||||||
$('#steps .step-container:nth-last-child(2) .insert-step').prop('disabled', false);
|
$("#steps .step-container:nth-last-child(2) .insert-step").prop('disabled',false);
|
||||||
} else {
|
} else {
|
||||||
stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]);
|
stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('#load-image').append(step.ui);
|
$("#load-image").append(step.ui);
|
||||||
}
|
}
|
||||||
$step('.toggle').on('click', () => {
|
$(step.ui.querySelector(".toggle")).on("click", () => {
|
||||||
$step('.toggleIcon').toggleClass('rotated');
|
$(step.ui.querySelector('.toggleIcon')).toggleClass('rotated');
|
||||||
$stepAll('.cal').collapse('toggle');
|
$(step.ui.querySelectorAll(".cal")).collapse('toggle');
|
||||||
});
|
});
|
||||||
|
|
||||||
$(step.imgElement).on('mousemove', _.debounce(() => imageHover(step), 150));
|
$(step.imgElement).on("mousemove", _.debounce(() => imageHover(step), 150));
|
||||||
$(step.imgElement).on('click', (e) => {e.preventDefault(); });
|
|
||||||
$stepAll('#color-picker').colorpicker();
|
|
||||||
|
|
||||||
function saveOptions(e) {
|
function saveOptions(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (optionsChanged){
|
if (optionsChanged){
|
||||||
$step('div.details')
|
$(step.ui.querySelector("div.details"))
|
||||||
.find('input,select')
|
.find("input,select")
|
||||||
.each(function(i, input) {
|
.each(function(i, input) {
|
||||||
$(input)
|
$(input)
|
||||||
.data('initValue', $(input).val())
|
.data('initValue', $(input).val())
|
||||||
.data('hasChangedBefore', false);
|
.data('hasChangedBefore', false);
|
||||||
step.options[$(input).attr('name')] = $(input).val();
|
step.options[$(input).attr("name")] = $(input).val();
|
||||||
});
|
});
|
||||||
_sequencer.run({ index: step.index - 1 });
|
_sequencer.run({ index: step.index - 1 });
|
||||||
|
|
||||||
// modify the url hash
|
// modify the url hash
|
||||||
urlHash.setUrlHashParameter('steps', _sequencer.toString());
|
urlHash.setUrlHashParameter("steps", _sequencer.toString())
|
||||||
// disable the save button
|
// disable the save button
|
||||||
$step('.btn-save').prop('disabled', true);
|
$(step.ui.querySelector('.btn-save')).prop('disabled', true);
|
||||||
optionsChanged = false;
|
optionsChanged = false;
|
||||||
changedInputs = 0;
|
changedInputs = 0;
|
||||||
}
|
}
|
||||||
@@ -224,19 +194,19 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0;
|
changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0;
|
||||||
optionsChanged = changedInputs > 0;
|
optionsChanged = changedInputs > 0;
|
||||||
|
|
||||||
$step('.btn-save').prop('disabled', !optionsChanged);
|
$(step.ui.querySelector('.btn-save')).prop('disabled', !optionsChanged);
|
||||||
return inputChanged;
|
return inputChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
var
|
var
|
||||||
changedInputs = 0,
|
changedInputs = 0,
|
||||||
optionsChanged = false;
|
optionsChanged = false;
|
||||||
$step('.input-form').on('submit', saveOptions);
|
$(step.ui.querySelector('.input-form')).on('submit', saveOptions);
|
||||||
$stepAll('.target').each(function(i, input) {
|
$(step.ui.querySelectorAll('.target')).each(function(i, input) {
|
||||||
$(input)
|
$(input)
|
||||||
.data('initValue', $(input).val())
|
.data('initValue', $(input).val())
|
||||||
.data('hasChangedBefore', false)
|
.data('hasChangedBefore', false)
|
||||||
.on('input change', function() {
|
.on('input', function() {
|
||||||
$(this)
|
$(this)
|
||||||
.focus()
|
.focus()
|
||||||
.data('hasChangedBefore',
|
.data('hasChangedBefore',
|
||||||
@@ -245,31 +215,31 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
$(this).data('initValue'),
|
$(this).data('initValue'),
|
||||||
$(this).data('hasChangedBefore')
|
$(this).data('hasChangedBefore')
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('input[type="range"]').on('input', function() {
|
$('input[type="range"]').on('input', function() {
|
||||||
$(this).next().html($(this).val());
|
$(this).next().html($(this).val());
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onDraw() {
|
function onDraw(step) {
|
||||||
$step('.load').show();
|
$(step.ui.querySelector(".load")).show();
|
||||||
$step('img').hide();
|
$(step.ui.querySelector("img")).hide();
|
||||||
$stepAll('.load-spin').show();
|
$(step.ui.querySelectorAll(".load-spin")).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onComplete(step) {
|
function onComplete(step) {
|
||||||
$step('img').show();
|
$(step.ui.querySelector("img")).show();
|
||||||
$stepAll('.load-spin').hide();
|
$(step.ui.querySelectorAll(".load-spin")).hide();
|
||||||
$step('.load').hide();
|
$(step.ui.querySelector(".load")).hide();
|
||||||
|
|
||||||
step.imgElement.src = (step.name == 'load-image') ? step.output.src : step.output;
|
step.imgElement.src = (step.name == "load-image") ? step.output.src : step.output;
|
||||||
var imgthumbnail = $step('.img-thumbnail').getDomElem();
|
var imgthumbnail = step.ui.querySelector(".img-thumbnail");
|
||||||
for (let index = 0; index < step.linkElements.length; index++) {
|
for (let index = 0; index < step.linkElements.length; index++) {
|
||||||
if (step.linkElements[index].contains(imgthumbnail))
|
if (step.linkElements[index].contains(imgthumbnail))
|
||||||
step.linkElements[index].href = step.imgElement.src;
|
step.linkElements[index].href = step.imgElement.src;
|
||||||
@@ -277,24 +247,14 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
|
|
||||||
// TODO: use a generalized version of this
|
// TODO: use a generalized version of this
|
||||||
function fileExtension(output) {
|
function fileExtension(output) {
|
||||||
return output.split('/')[1].split(';')[0];
|
return output.split("/")[1].split(";")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$stepAll('.download-btn').on('click', () => {
|
|
||||||
|
|
||||||
for (let index = 0; index < step.linkElements.length; index++) {
|
for (let index = 0; index < step.linkElements.length; index++) {
|
||||||
|
|
||||||
var element = document.createElement('a');
|
step.linkElements[index].download = step.name + "." + fileExtension(step.imgElement.src);
|
||||||
element.setAttribute('href', step.linkElements[index].href);
|
step.linkElements[index].target = "_blank";
|
||||||
element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src));
|
|
||||||
element.style.display = 'none';
|
|
||||||
document.body.appendChild(element);
|
|
||||||
|
|
||||||
element.click();
|
|
||||||
|
|
||||||
document.body.removeChild(element);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// fill inputs with stored step options
|
// fill inputs with stored step options
|
||||||
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
|
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
|
||||||
@@ -302,19 +262,19 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
var outputs = _sequencer.modulesInfo(step.name).outputs;
|
var outputs = _sequencer.modulesInfo(step.name).outputs;
|
||||||
for (var i in inputs) {
|
for (var i in inputs) {
|
||||||
if (step.options[i] !== undefined) {
|
if (step.options[i] !== undefined) {
|
||||||
if (inputs[i].type.toLowerCase() === 'input')
|
if (inputs[i].type.toLowerCase() === "input")
|
||||||
$step('div[name="' + i + '"] input')
|
$(step.ui.querySelector('div[name="' + i + '"] input'))
|
||||||
.val(step.options[i])
|
.val(step.options[i])
|
||||||
.data('initValue', step.options[i]);
|
.data('initValue', step.options[i]);
|
||||||
if (inputs[i].type.toLowerCase() === 'select')
|
if (inputs[i].type.toLowerCase() === "select")
|
||||||
$step('div[name="' + i + '"] select')
|
$(step.ui.querySelector('div[name="' + i + '"] select'))
|
||||||
.val(step.options[i])
|
.val(step.options[i])
|
||||||
.data('initValue', step.options[i]);
|
.data('initValue', step.options[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var i in outputs) {
|
for (var i in outputs) {
|
||||||
if (step[i] !== undefined)
|
if (step[i] !== undefined)
|
||||||
$step('div[name="' + i + '"] input')
|
$(step.ui.querySelector('div[name="' + i + '"] input'))
|
||||||
.val(step[i]);
|
.val(step[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,13 +295,13 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
var xPos = e.pageX - offset.left;
|
var xPos = e.pageX - offset.left;
|
||||||
var yPos = e.pageY - offset.top;
|
var yPos = e.pageY - offset.top;
|
||||||
var myData = context.getImageData(xPos, yPos, 1, 1);
|
var myData = context.getImageData(xPos, yPos, 1, 1);
|
||||||
img[0].title = 'rgb: ' + myData.data[0] + ',' + myData.data[1] + ',' + myData.data[2];//+ rgbdata;
|
img[0].title = "rgb: " +myData.data[0]+","+ myData.data[1]+","+myData.data[2];//+ rgbdata;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRemove(step) {
|
function onRemove(step) {
|
||||||
step.ui.remove();
|
step.ui.remove();
|
||||||
$('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true);
|
$("#steps .step-container:nth-last-child(1) .insert-step").prop('disabled',true);
|
||||||
$('div[class*=imgareaselect-]').remove();
|
$('div[class*=imgareaselect-]').remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +314,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
var notification = document.createElement('span');
|
var notification = document.createElement('span');
|
||||||
notification.innerHTML = ' <i class="fa fa-info-circle" aria-hidden="true"></i> ' + msg ;
|
notification.innerHTML = ' <i class="fa fa-info-circle" aria-hidden="true"></i> ' + msg ;
|
||||||
notification.id = id;
|
notification.id = id;
|
||||||
notification.classList.add('notification');
|
notification.classList.add("notification");
|
||||||
|
|
||||||
$('body').append(notification);
|
$('body').append(notification);
|
||||||
}
|
}
|
||||||
@@ -371,13 +331,14 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
onDraw: onDraw,
|
onDraw: onDraw,
|
||||||
notify: notify,
|
notify: notify,
|
||||||
imageHover: imageHover
|
imageHover: imageHover
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof window === 'undefined'){
|
if(typeof window === "undefined"){
|
||||||
module.exports={
|
module.exports={
|
||||||
DefaultHtmlStepUi: DefaultHtmlStepUi
|
DefaultHtmlStepUi: DefaultHtmlStepUi
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DefaultHtmlStepUi;
|
module.exports = DefaultHtmlStepUi;
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ function generatePreview(previewStepName, customValues, path, selector) {
|
|||||||
var previewSequencer = ImageSequencer();
|
var previewSequencer = ImageSequencer();
|
||||||
function insertPreview(src) {
|
function insertPreview(src) {
|
||||||
var img = document.createElement('img');
|
var img = document.createElement('img');
|
||||||
img.classList.add('img-thumbnail');
|
img.classList.add('img-thumbnail')
|
||||||
img.classList.add('no-border');
|
img.classList.add('no-border');
|
||||||
img.src = src;
|
img.src = src;
|
||||||
$(img).css('max-width', '200%');
|
$(img).css("max-width", "200%");
|
||||||
$(img).css('transform', 'translateX(-20%)');
|
$(img).css("transform", "translateX(-20%)");
|
||||||
$(selector + ' .radio-group').find('div').each(function() {
|
$(selector + ' .radio-group').find('div').each(function() {
|
||||||
if ($(this).find('div').attr('data-value') === previewStepName) {
|
if ($(this).find('div').attr('data-value') === previewStepName) {
|
||||||
$(this).find('div').append(img);
|
$(this).find('div').append(img);
|
||||||
@@ -16,16 +16,13 @@ function generatePreview(previewStepName, customValues, path, selector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadPreview() {
|
function loadPreview() {
|
||||||
if (previewStepName === 'crop') {
|
if (previewStepName === "crop") {
|
||||||
previewSequencer.addSteps(previewStepName, customValues).run(insertPreview);
|
previewSequencer.addSteps(previewStepName, customValues).run(insertPreview);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
previewSequencer.addSteps(previewStepName, { [previewStepName]: customValues }).run(insertPreview);
|
previewSequencer.addSteps(previewStepName, { [previewStepName]: customValues }).run(insertPreview);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(previewStepName === 'resize')
|
|
||||||
insertPreview(path);
|
|
||||||
else
|
|
||||||
previewSequencer.loadImage(path, loadPreview);
|
previewSequencer.loadImage(path, loadPreview);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,45 +30,26 @@ function updatePreviews(src, selector) {
|
|||||||
$(selector+' img').remove();
|
$(selector+' img').remove();
|
||||||
|
|
||||||
var previewSequencerSteps = {
|
var previewSequencerSteps = {
|
||||||
'resize': '125%',
|
"resize": "125%",
|
||||||
'brightness': '175',
|
"brightness": "175",
|
||||||
'saturation': '0.5',
|
"saturation": "0.5",
|
||||||
'rotate': 90,
|
"rotate": 90,
|
||||||
'contrast': 90,
|
"contrast": 90,
|
||||||
'crop': {
|
"crop": {
|
||||||
'x': 0,
|
"x": 0,
|
||||||
'y': 0,
|
"y": 0,
|
||||||
'w': '(50%)',
|
"w": "(50%)",
|
||||||
'h': '(50%)',
|
"h": "(50%)",
|
||||||
'noUI': true
|
"noUI": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
var img = new Image();
|
|
||||||
img.onload = function(){
|
|
||||||
var height = img.height;
|
|
||||||
var width = img.width;
|
|
||||||
|
|
||||||
let percentage = (80 / height) * 100; //take the min resize value that fits the preview area => (new-width/orig_ht) - '80 as the preview area has 80*80 dimension
|
|
||||||
percentage = Math.max((80 / width) * 100, percentage); // make sure that one dimension doesn't resize greater, leading distorting preview-area fitting
|
|
||||||
percentage = Math.ceil(percentage);
|
|
||||||
|
|
||||||
var sequencer = ImageSequencer();
|
|
||||||
|
|
||||||
sequencer.loadImage(src, function(){
|
|
||||||
this.addSteps('resize', {['resize']: percentage + '%'});
|
|
||||||
this.run((src)=>{
|
|
||||||
Object.keys(previewSequencerSteps).forEach(function (step, index) {
|
Object.keys(previewSequencerSteps).forEach(function (step, index) {
|
||||||
generatePreview(step, Object.values(previewSequencerSteps)[index], src, selector);
|
generatePreview(step, Object.values(previewSequencerSteps)[index], src, selector);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
img.src = src;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
generatePreview : generatePreview,
|
generatePreview : generatePreview,
|
||||||
updatePreviews : updatePreviews
|
updatePreviews : updatePreviews
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -65,100 +65,99 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function selectNewStepUi($step) {
|
function selectNewStepUi() {
|
||||||
var insertSelect = $step('.insert-step-select');
|
var insertSelect = $(step.ui.querySelector('.insert-step-select'))
|
||||||
var m = insertSelect.val();
|
var m = insertSelect.val();
|
||||||
$step('.insertDiv .info').html(_sequencer.modulesInfo(m).description);
|
$(step.ui.querySelector('.insertDiv .info')).html(_sequencer.modulesInfo(m).description);
|
||||||
$step('.insertDiv .add-step-btn').prop('disabled', false);
|
$(step.ui.querySelector('.insertDiv .add-step-btn')).prop("disabled", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var toggleDiv = function($step, callback = function(){}){
|
var toggleDiv = function(callback = function(){}){
|
||||||
$step('.insertDiv').collapse('toggle');
|
$(step.ui.querySelector('.insertDiv')).collapse('toggle');
|
||||||
if ($step('.insert-text').css('display') != 'none'){
|
if ($(step.ui.querySelector('.insert-text')).css('display') != "none"){
|
||||||
$step('.insert-text').fadeToggle(200, function(){$step('.no-insert-text').fadeToggle(200, callback);});
|
$(step.ui.querySelector('.insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, callback)})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$step('.no-insert-text').fadeToggle(200, function(){$step('.insert-text').fadeToggle(200, callback);});
|
$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.insert-text')).fadeToggle(200, callback)})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
insertStep = function (id) {
|
insertStep = function (id) {
|
||||||
const $step = step.ui.$step,
|
|
||||||
$stepAll = step.ui.$stepAll;
|
|
||||||
var modulesInfo = _sequencer.modulesInfo();
|
var modulesInfo = _sequencer.modulesInfo();
|
||||||
var parser = new DOMParser();
|
var parser = new DOMParser();
|
||||||
var addStepUI = stepUI();
|
var addStepUI = stepUI();
|
||||||
addStepUI = parser.parseFromString(addStepUI, 'text/html').querySelector('div');
|
addStepUI = parser.parseFromString(addStepUI, "text/html").querySelector("div")
|
||||||
if ($step('.insertDiv').length > 0){
|
|
||||||
toggleDiv($step);
|
if ($(step.ui.querySelector('.insertDiv')).length > 0){
|
||||||
|
toggleDiv();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
step.ui
|
step.ui
|
||||||
.querySelector('div.step')
|
.querySelector("div.step")
|
||||||
.insertAdjacentElement('afterend',
|
.insertAdjacentElement('afterend',
|
||||||
addStepUI
|
addStepUI
|
||||||
);
|
);
|
||||||
toggleDiv($step, function(){
|
toggleDiv(function(){
|
||||||
insertPreview.updatePreviews(step.output, '.insertDiv');
|
insertPreview.updatePreviews(step.output, '.insertDiv');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$step('.insertDiv .close-insert-box').off('click').on('click', function(){toggleDiv(function(){});});
|
$(step.ui.querySelector('.insertDiv .close-insert-box')).off('click').on('click', function(){toggleDiv(function(){})});
|
||||||
|
|
||||||
var insertStepSelect = $step('.insert-step-select');
|
var insertStepSelect = $(step.ui.querySelector('.insert-step-select'));
|
||||||
insertStepSelect.html('');
|
insertStepSelect.html("");
|
||||||
// Add modules to the insertStep dropdown
|
// Add modules to the insertStep dropdown
|
||||||
for (var m in modulesInfo) {
|
for (var m in modulesInfo) {
|
||||||
if (modulesInfo[m] !== undefined)
|
if (modulesInfo[m] !== undefined)
|
||||||
insertStepSelect.append(
|
insertStepSelect.append(
|
||||||
'<option value="' + m + '">' + modulesInfo[m].name + '</option>'
|
'<option value="' + m + '">' + modulesInfo[m].name + "</option>"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
insertStepSelect.selectize({
|
insertStepSelect.selectize({
|
||||||
sortField: 'text'
|
sortField: 'text'
|
||||||
});
|
});
|
||||||
$step('.inserDiv .add-step-btn').prop('disabled', true);
|
$(step.ui.querySelector('.inserDiv .add-step-btn')).prop('disabled', true);
|
||||||
|
|
||||||
insertStepSelect.append('<option value="" disabled selected>Select a Module</option>');
|
insertStepSelect.append('<option value="" disabled selected>Select a Module</option>');
|
||||||
$step('.insertDiv .radio-group .radio').on('click', function () {
|
$(step.ui.querySelector('.insertDiv .radio-group .radio')).on("click", function () {
|
||||||
$(this).parent().find('.radio').removeClass('selected');
|
$(this).parent().find('.radio').removeClass('selected');
|
||||||
$(this).addClass('selected');
|
$(this).addClass('selected');
|
||||||
newStep = $(this).attr('data-value');
|
newStep = $(this).attr('data-value');
|
||||||
$step('.insert-step-select').val(newStep);
|
$(step.ui.querySelector('.insert-step-select')).val(newStep);
|
||||||
selectNewStepUi($step);
|
selectNewStepUi();
|
||||||
insert(id, $step);
|
insert(id);
|
||||||
$(this).removeClass('selected');
|
$(this).removeClass('selected');
|
||||||
});
|
});
|
||||||
insertStepSelect.on('change', () => {selectNewStepUi($step);});
|
insertStepSelect.on('change', selectNewStepUi);
|
||||||
$step('.insertDiv .add-step-btn').on('click', function () { insert(id, $step); });
|
$(step.ui.querySelector('.insertDiv .add-step-btn')).on('click', function () { insert(id) });
|
||||||
};
|
}
|
||||||
|
|
||||||
function insert(id, $step) {
|
function insert(id) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var insertStepSelect = $step('.insert-step-select');
|
var insertStepSelect = $(step.ui.querySelector('.insert-step-select'));
|
||||||
if (insertStepSelect.val() == 'none') return;
|
if (insertStepSelect.val() == "none") return;
|
||||||
|
|
||||||
var newStepName = insertStepSelect.val();
|
var newStepName = insertStepSelect.val()
|
||||||
toggleDiv($step);
|
toggleDiv();
|
||||||
var sequenceLength = 1;
|
var sequenceLength = 1;
|
||||||
if (sequencer.sequences[newStepName]) {
|
if (sequencer.sequences[newStepName]) {
|
||||||
sequenceLength = sequencer.sequences[newStepName].length;
|
sequenceLength = sequencer.sequences[newStepName].length;
|
||||||
} else if (sequencer.modules[newStepName][1]['length']) {
|
} else if (sequencer.modules[newStepName][1]["length"]) {
|
||||||
sequenceLength = sequencer.modules[newStepName][1]['length'];
|
sequenceLength = sequencer.modules[newStepName][1]["length"];
|
||||||
}
|
}
|
||||||
_sequencer
|
_sequencer
|
||||||
.insertSteps(id + 1, newStepName).run({ index: id });
|
.insertSteps(id + 1, newStepName).run({ index: id });
|
||||||
|
|
||||||
// add to URL hash too
|
// add to URL hash too
|
||||||
urlHash.setUrlHashParameter('steps', _sequencer.toString());
|
urlHash.setUrlHashParameter("steps", _sequencer.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
insertStep
|
insertStep
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
module.exports = IntermediateHtmlStepUi;
|
module.exports = IntermediateHtmlStepUi;
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
/**
|
|
||||||
* @method $scope
|
|
||||||
* @param {"DOMNode"} scope A DOM Node as the scope
|
|
||||||
*/
|
|
||||||
function $scope(scope) {
|
|
||||||
return function(queryString){
|
|
||||||
var element = $(scope.querySelector(queryString));
|
|
||||||
|
|
||||||
element.elem = function(queryString){
|
|
||||||
return new $scope(scope)(queryString);
|
|
||||||
};
|
|
||||||
element.elemAll = function(queryString){
|
|
||||||
return new $scopeAll(scope)(queryString);
|
|
||||||
};
|
|
||||||
element.getDomElem = function(i = 0){
|
|
||||||
return element[i];
|
|
||||||
};
|
|
||||||
element.getScope = () => scope;
|
|
||||||
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @method $scopeAll
|
|
||||||
* @param {"DOMNode"} scope A DOM Node as the scope
|
|
||||||
*/
|
|
||||||
function $scopeAll(scope){
|
|
||||||
return function(queryString){
|
|
||||||
var element = $(scope.querySelectorAll(queryString));
|
|
||||||
|
|
||||||
element.elem = function(queryString){
|
|
||||||
return new $scope(scope)(queryString);
|
|
||||||
};
|
|
||||||
element.elemAll = function(queryString){
|
|
||||||
return new $scopeAll(scope)(queryString);
|
|
||||||
};
|
|
||||||
element.getDomElem = function(i = 0){
|
|
||||||
return element[i];
|
|
||||||
};
|
|
||||||
element.getScope = () => scope;
|
|
||||||
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @method scopeSelector
|
|
||||||
* @description A scoped jQuery selector
|
|
||||||
* @param {"DOMNode"} scope DOM Node as the scope
|
|
||||||
*/
|
|
||||||
function scopeSelector(scope){
|
|
||||||
return $scope(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @method scopeSelectorAll
|
|
||||||
* @description A scoped jQuery multiple selector
|
|
||||||
* @param {"DOMNode} scope DOM Node as the scope
|
|
||||||
*/
|
|
||||||
function scopeSelectorAll(scope){
|
|
||||||
return $scopeAll(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
scopeSelector,
|
|
||||||
scopeSelectorAll
|
|
||||||
};
|
|
||||||
@@ -46,4 +46,4 @@ module.exports = {
|
|||||||
setUrlHashParameter: setUrlHashParameter,
|
setUrlHashParameter: setUrlHashParameter,
|
||||||
getUrlHashParameters: getUrlHashParameters,
|
getUrlHashParameters: getUrlHashParameters,
|
||||||
setUrlHashParameters: setUrlHashParameters
|
setUrlHashParameters: setUrlHashParameters
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ self.addEventListener('fetch', function(event) {
|
|||||||
caches.open(staticCacheName).then(function(cache) {
|
caches.open(staticCacheName).then(function(cache) {
|
||||||
return cache.match(event.request).then(function (response) {
|
return cache.match(event.request).then(function (response) {
|
||||||
return response || fetch(event.request).then(function(response) {
|
return response || fetch(event.request).then(function(response) {
|
||||||
if(event.request.method == 'GET')
|
if(event.request.method == "GET")
|
||||||
cache.put(event.request, response.clone());
|
cache.put(event.request, response.clone());
|
||||||
return response;
|
return response;
|
||||||
});
|
});
|
||||||
|
|||||||
52
index.js
52
index.js
@@ -1,14 +1,14 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
require('./src/ImageSequencer');
|
require('./src/ImageSequencer');
|
||||||
sequencer = ImageSequencer({ ui: true });
|
sequencer = ImageSequencer({ ui: false });
|
||||||
var fs = require('fs');
|
var fs = require('fs')
|
||||||
var program = require('commander');
|
var program = require('commander');
|
||||||
var utils = require('./src/CliUtils');
|
var utils = require('./src/CliUtils')
|
||||||
|
|
||||||
var saveSequence = require('./src/cli/saveSequence.js');
|
var saveSequence = require('./src/cli/saveSequence.js')
|
||||||
var installModule = require('./src/cli/installModule.js');
|
var installModule = require('./src/cli/installModule.js')
|
||||||
var sequencerSteps = require('./src/cli/sequencerSteps.js');
|
var sequencerSteps = require('./src/cli/sequencerSteps.js')
|
||||||
|
|
||||||
function exit(message) {
|
function exit(message) {
|
||||||
console.error(message);
|
console.error(message);
|
||||||
@@ -16,39 +16,39 @@ function exit(message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
program
|
program
|
||||||
.version('0.1.0')
|
.version("0.1.0")
|
||||||
.option('-i, --image [PATH/URL]', 'Input image URL')
|
.option("-i, --image [PATH/URL]", "Input image URL")
|
||||||
.option('-s, --step [step-name]', 'Name of the step to be added.')
|
.option("-s, --step [step-name]", "Name of the step to be added.")
|
||||||
.option('-o, --output [PATH]', 'Directory where output will be stored.')
|
.option("-o, --output [PATH]", "Directory where output will be stored.")
|
||||||
.option('-b, --basic', 'Basic mode outputs only final image')
|
.option("-b, --basic", "Basic mode outputs only final image")
|
||||||
.option('-c, --config [Object]', 'Options for the step')
|
.option("-c, --config [Object]", "Options for the step")
|
||||||
.option('--save-sequence [string]', 'Name space separated with Stringified sequence')
|
.option("--save-sequence [string]", "Name space separated with Stringified sequence")
|
||||||
.option('--install-module [string]', 'Module name space seaprated npm package name')
|
.option('--install-module [string]', "Module name space seaprated npm package name")
|
||||||
.parse(process.argv);
|
.parse(process.argv);
|
||||||
|
|
||||||
if (program.saveSequence) saveSequence(program, sequencer);
|
if (program.saveSequence) saveSequence(program, sequencer)
|
||||||
|
|
||||||
else if (program.installModule) installModule(program, sequencer);
|
else if (program.installModule) installModule(program, sequencer)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
// Parse step into an array to allow for multiple steps.
|
// Parse step into an array to allow for multiple steps.
|
||||||
if (!program.step) exit('No steps passed');
|
if (!program.step) exit("No steps passed");
|
||||||
program.step = program.step.split(' ');
|
program.step = program.step.split(" ");
|
||||||
|
|
||||||
// User must input an image.
|
// User must input an image.
|
||||||
if (!program.image) exit('Can\'t read file.');
|
if (!program.image) exit("Can't read file.");
|
||||||
|
|
||||||
// User must input an image.
|
// User must input an image.
|
||||||
fs.access(program.image, function(err) {
|
fs.access(program.image, function(err) {
|
||||||
if (err) exit('Can\'t read file.');
|
if (err) exit("Can't read file.");
|
||||||
});
|
});
|
||||||
|
|
||||||
// User must input a step. If steps exist, check that every step is a valid step.
|
// User must input a step. If steps exist, check that every step is a valid step.
|
||||||
if (!program.step || !(utils.validateSteps(program.step, sequencer)))
|
if (!program.step || !(utils.validateSteps(program.step, sequencer)))
|
||||||
exit('Please ensure all steps are valid.');
|
exit("Please ensure all steps are valid.");
|
||||||
|
|
||||||
// If there's no user defined output directory, select a default directory.
|
// If there's no user defined output directory, select a default directory.
|
||||||
program.output = program.output || './output/';
|
program.output = program.output || "./output/";
|
||||||
|
|
||||||
// Set sequencer to log module outputs, if any.
|
// Set sequencer to log module outputs, if any.
|
||||||
sequencer.setUI({
|
sequencer.setUI({
|
||||||
@@ -57,7 +57,7 @@ else {
|
|||||||
step.info = sequencer.modulesInfo(step.name);
|
step.info = sequencer.modulesInfo(step.name);
|
||||||
|
|
||||||
for (var output in step.info.outputs) {
|
for (var output in step.info.outputs) {
|
||||||
console.log('[' + program.step + ']: ' + output + ' = ' + step[output]);
|
console.log("[" + program.step + "]: " + output + " = " + step[output]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
notify: function(msg) {
|
notify: function(msg) {
|
||||||
@@ -68,8 +68,8 @@ else {
|
|||||||
// Finally, if everything is alright, load the image, add the steps and run the sequencer.
|
// Finally, if everything is alright, load the image, add the steps and run the sequencer.
|
||||||
sequencer.loadImages(program.image, function() {
|
sequencer.loadImages(program.image, function() {
|
||||||
console.warn(
|
console.warn(
|
||||||
'\x1b[33m%s\x1b[0m',
|
"\x1b[33m%s\x1b[0m",
|
||||||
'Please wait \n output directory generated will be empty until the execution is complete'
|
"Please wait \n output directory generated will be empty until the execution is complete"
|
||||||
);
|
);
|
||||||
|
|
||||||
//Generate the Output Directory
|
//Generate the Output Directory
|
||||||
@@ -82,7 +82,7 @@ else {
|
|||||||
outputFilename = null;
|
outputFilename = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
sequencerSteps(program, sequencer, outputFilename);
|
sequencerSteps(program, sequencer, outputFilename)
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
4975
package-lock.json
generated
4975
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@@ -1,21 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "image-sequencer",
|
"name": "image-sequencer",
|
||||||
"version": "3.5.1",
|
"version": "3.0.1",
|
||||||
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
|
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
|
||||||
"main": "src/ImageSequencer.js",
|
"main": "src/ImageSequencer.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
|
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
|
||||||
"test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/*.js | tap-spec; node test/core/sequencer/benchmark.js; browserify test/core/sequencer/meta-modules.js test/core/sequencer/image-sequencer.js test/core/sequencer/chain.js test/core/sequencer/replace.js test/core/sequencer/import-export.js test/core/sequencer/run.js test/core/sequencer/dynamic-imports.js test/core/util/*.js | tape-run --render=\"tap-spec\"",
|
"test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/canvas-resize.js test/core/modules/QR.js | tap-spec; browserify test/core/modules/image-sequencer.js test/core/modules/chain.js test/core/modules/meta-modules.js test/core/modules/replace.js test/core/modules/import-export.js test/core/modules/run.js test/core/modules/dynamic-imports.js test/core/util/parse-input.js test/core/modules/benchmark.js| tape-run --render=\"tap-spec\"",
|
||||||
"test-ui": "node node_modules/jasmine/bin/jasmine test/ui/spec/*.js",
|
"test-ui": "jasmine test/spec/*.js",
|
||||||
"setup": "npm i && npm i -g grunt grunt-cli && grunt build",
|
"setup": "npm i && npm i -g grunt grunt-cli && grunt build",
|
||||||
"start": "grunt serve"
|
"start": "grunt serve"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
|
||||||
"*.js": [
|
|
||||||
"./node_modules/.bin/eslint --fix",
|
|
||||||
"git add"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/publiclab/image-sequencer.git"
|
"url": "git+https://github.com/publiclab/image-sequencer.git"
|
||||||
@@ -30,37 +24,26 @@
|
|||||||
"url": "https://github.com/publiclab/image-sequencer/issues"
|
"url": "https://github.com/publiclab/image-sequencer/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"atob": "^2.1.2",
|
|
||||||
"base64-img": "^1.0.4",
|
|
||||||
"bootstrap": "~3.4.0",
|
"bootstrap": "~3.4.0",
|
||||||
"bootstrap-colorpicker": "^2.5.3",
|
|
||||||
"buffer": "~5.2.1",
|
"buffer": "~5.2.1",
|
||||||
"commander": "^2.11.0",
|
"commander": "^2.11.0",
|
||||||
"compressorjs": "^1.0.5",
|
|
||||||
"data-uri-to-buffer": "^2.0.0",
|
"data-uri-to-buffer": "^2.0.0",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
"eslint": "^5.16.0",
|
|
||||||
"fisheyegl": "^0.1.2",
|
"fisheyegl": "^0.1.2",
|
||||||
"font-awesome": "~4.7.0",
|
"font-awesome": "~4.7.0",
|
||||||
"geotiff": "^1.0.0-beta.6",
|
"geotiff": "^1.0.0-beta.6",
|
||||||
"get-pixels": "~3.3.0",
|
"get-pixels": "~3.3.0",
|
||||||
"gifshot": "^0.4.5",
|
"gifshot": "^0.4.5",
|
||||||
"glfx": "0.0.4",
|
|
||||||
"gpu.js": "^2.0.0-rc.12",
|
|
||||||
"image-sequencer-invert": "^1.0.0",
|
"image-sequencer-invert": "^1.0.0",
|
||||||
"imagejs": "0.0.9",
|
"imagejs": "0.0.9",
|
||||||
"imagemin": "^7.0.0",
|
|
||||||
"imagemin-jpegtran": "^6.0.0",
|
|
||||||
"imagemin-pngquant": "^8.0.0",
|
|
||||||
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
|
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
|
||||||
"istanbul": "^0.4.5",
|
"istanbul": "^0.4.5",
|
||||||
"jasmine": "^3.4.0",
|
|
||||||
"jquery": "^3.3.1",
|
"jquery": "^3.3.1",
|
||||||
"jsdom": "^15.0.0",
|
"jsdom": "^14.0.0",
|
||||||
"jsqr": "^1.1.1",
|
"jsqr": "^1.1.1",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"ndarray": "^1.0.18",
|
"ndarray": "^1.0.18",
|
||||||
"opencv.js": "^1.2.1",
|
"ndarray-gaussian-filter": "^1.0.0",
|
||||||
"ora": "^3.0.0",
|
"ora": "^3.0.0",
|
||||||
"pace": "0.0.4",
|
"pace": "0.0.4",
|
||||||
"puppeteer": "^1.14.0",
|
"puppeteer": "^1.14.0",
|
||||||
@@ -68,42 +51,29 @@
|
|||||||
"readline-sync": "^1.4.7",
|
"readline-sync": "^1.4.7",
|
||||||
"save-pixels": "~2.3.4",
|
"save-pixels": "~2.3.4",
|
||||||
"selectize": "^0.12.6",
|
"selectize": "^0.12.6",
|
||||||
"spawn-sync": "^2.0.0",
|
"urify": "^2.1.1"
|
||||||
"urify": "^2.1.1",
|
|
||||||
"webgl-distort": "0.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.4.3",
|
"base64-img": "^1.0.4",
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.4.3",
|
|
||||||
"@babel/plugin-syntax-object-rest-spread": "^7.2.0",
|
|
||||||
"babelify": "^10.0.0",
|
|
||||||
"browserify": "16.2.3",
|
"browserify": "16.2.3",
|
||||||
"eslint": "^5.16.0",
|
|
||||||
"grunt": "^1.0.3",
|
"grunt": "^1.0.3",
|
||||||
"grunt-browser-sync": "^2.2.0",
|
"grunt-browser-sync": "^2.2.0",
|
||||||
"grunt-browserify": "^5.0.0",
|
"grunt-browserify": "^5.0.0",
|
||||||
"grunt-contrib-concat": "^1.0.1",
|
"grunt-contrib-concat": "^1.0.1",
|
||||||
"grunt-contrib-uglify-es": "^3.3.0",
|
"grunt-contrib-uglify-es": "^3.3.0",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"husky": "^2.2.0",
|
|
||||||
"image-filter-core": "~2.0.2",
|
"image-filter-core": "~2.0.2",
|
||||||
"image-filter-threshold": "~2.0.1",
|
"image-filter-threshold": "~2.0.1",
|
||||||
"jasmine-core": "^3.3.0",
|
"jasmine-core": "^3.3.0",
|
||||||
"jasmine-jquery": "^2.1.1",
|
"jasmine-jquery": "^2.1.1",
|
||||||
"jasmine-spec-reporter": "^4.2.1",
|
"jasmine-spec-reporter": "^4.2.1",
|
||||||
"lint-staged": "^9.1.0",
|
|
||||||
"looks-same": "^7.0.0",
|
"looks-same": "^7.0.0",
|
||||||
"matchdep": "^2.0.0",
|
"matchdep": "^2.0.0",
|
||||||
"tap-spec": "^5.0.0",
|
"tap-spec": "^5.0.0",
|
||||||
"tape": "^4.9.2",
|
"tape": "^4.9.2",
|
||||||
"tape-run": "^6.0.0",
|
"tape-run": "^5.0.0",
|
||||||
"uglify-es": "^3.3.7"
|
"uglify-es": "^3.3.7"
|
||||||
},
|
},
|
||||||
"husky": {
|
|
||||||
"hooks": {
|
|
||||||
"pre-commit": "lint-staged"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"homepage": "https://sequencer.publiclab.org",
|
"homepage": "https://sequencer.publiclab.org",
|
||||||
"bin": {
|
"bin": {
|
||||||
"sequencer": "./index.js"
|
"sequencer": "./index.js"
|
||||||
|
|||||||
42
spec/defaultHtmlSequencerUi.spec.js
Normal file
42
spec/defaultHtmlSequencerUi.spec.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
describe('Default sequencer HTML', function() {
|
||||||
|
|
||||||
|
var DefaultHtmlSequencerUi = require('../examples/lib/defaultHtmlSequencerUi')
|
||||||
|
var sequencer = require('../src/ImageSequencer')()
|
||||||
|
var defaultHtmlSequencerUi;
|
||||||
|
|
||||||
|
beforeEach(()=>{
|
||||||
|
defaultHtmlSequencerUi = new DefaultHtmlSequencerUi(sequencer)
|
||||||
|
|
||||||
|
spyOn(defaultHtmlSequencerUi,'onLoad')
|
||||||
|
spyOn(defaultHtmlSequencerUi,'selectNewStepUi')
|
||||||
|
spyOn(defaultHtmlSequencerUi,'removeStepUi')
|
||||||
|
spyOn(defaultHtmlSequencerUi,'addStepUi')
|
||||||
|
spyOn(defaultHtmlSequencerUi,'importStepsFromUrlHash')
|
||||||
|
|
||||||
|
defaultHtmlSequencerUi.onLoad()
|
||||||
|
defaultHtmlSequencerUi.selectNewStepUi()
|
||||||
|
defaultHtmlSequencerUi.addStepUi()
|
||||||
|
defaultHtmlSequencerUi.removeStepUi()
|
||||||
|
defaultHtmlSequencerUi.importStepsFromUrlHash()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('load default ui', function() {
|
||||||
|
expect(defaultHtmlSequencerUi.onLoad).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('select step ui', function() {
|
||||||
|
expect(defaultHtmlSequencerUi.selectNewStepUi).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('add step ui', function() {
|
||||||
|
expect(defaultHtmlSequencerUi.addStepUi).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('remove step ui', function() {
|
||||||
|
expect(defaultHtmlSequencerUi.removeStepUi).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('import options from url', function() {
|
||||||
|
expect(defaultHtmlSequencerUi.importStepsFromUrlHash).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
61
spec/defaultHtmlStepUi.spec.js
Normal file
61
spec/defaultHtmlStepUi.spec.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
var { JSDOM } = require('jsdom');
|
||||||
|
var DOM = new JSDOM(`<body></body>`);
|
||||||
|
|
||||||
|
global.document = DOM.window.document;
|
||||||
|
|
||||||
|
describe('Sequencer step HTML', function() {
|
||||||
|
|
||||||
|
var DefaultHtmlStepUi = require('../examples/lib/defaultHtmlStepUi')
|
||||||
|
var sequencer = require('../src/ImageSequencer')()
|
||||||
|
var defaultHtmlStepUi;
|
||||||
|
var step = 'brightness'
|
||||||
|
var options = {
|
||||||
|
name: "Brightness",
|
||||||
|
description: "Change the brightness of the image by given percent value"
|
||||||
|
}
|
||||||
|
// options = JSON.parse(options)
|
||||||
|
|
||||||
|
beforeEach(()=>{
|
||||||
|
defaultHtmlStepUi = new DefaultHtmlStepUi(sequencer)
|
||||||
|
|
||||||
|
spyOn(defaultHtmlStepUi,'getPreview')
|
||||||
|
spyOn(defaultHtmlStepUi,'onSetup')
|
||||||
|
spyOn(defaultHtmlStepUi,'onComplete')
|
||||||
|
spyOn(defaultHtmlStepUi,'onDraw')
|
||||||
|
spyOn(defaultHtmlStepUi,'onRemove')
|
||||||
|
spyOn(defaultHtmlStepUi,'notify')
|
||||||
|
|
||||||
|
defaultHtmlStepUi.getPreview()
|
||||||
|
defaultHtmlStepUi.onSetup(step,options)
|
||||||
|
defaultHtmlStepUi.onComplete(step)
|
||||||
|
defaultHtmlStepUi.onDraw(step)
|
||||||
|
defaultHtmlStepUi.onRemove(step)
|
||||||
|
defaultHtmlStepUi.notify('Step removed','remove-notification')
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
it('result preview ui', function() {
|
||||||
|
expect(defaultHtmlStepUi.getPreview).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('load initial setup ui', function() {
|
||||||
|
expect(defaultHtmlStepUi.onSetup).toHaveBeenCalledWith(step,options)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('load completion ui', function() {
|
||||||
|
expect(defaultHtmlStepUi.onComplete).toHaveBeenCalledWith(step)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('draw step ui', function() {
|
||||||
|
expect(defaultHtmlStepUi.onDraw).toHaveBeenCalledWith(step)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('remove step ui', function() {
|
||||||
|
expect(defaultHtmlStepUi.onRemove).toHaveBeenCalledWith(step)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('notification ui', function() {
|
||||||
|
expect(defaultHtmlStepUi.notify).toHaveBeenCalledWith('Step removed','remove-notification')
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
26
spec/insertPreview.spec.js
Normal file
26
spec/insertPreview.spec.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
describe('Preview UI HTML', function() {
|
||||||
|
|
||||||
|
var InsertPreview = require('../examples/lib/insertPreview')
|
||||||
|
var sequencer = require('../src/ImageSequencer')()
|
||||||
|
var insertPreview;
|
||||||
|
var options = { brightness: 50 }
|
||||||
|
|
||||||
|
beforeEach(()=>{
|
||||||
|
insertPreview = InsertPreview
|
||||||
|
|
||||||
|
spyOn(insertPreview,'generatePreview')
|
||||||
|
spyOn(insertPreview,'updatePreviews')
|
||||||
|
|
||||||
|
insertPreview.generatePreview('brightness',options,'src','selector')
|
||||||
|
insertPreview.updatePreviews('src','selector')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('generate preview ui', function() {
|
||||||
|
expect(insertPreview.generatePreview).toHaveBeenCalledWith('brightness',options,'src','selector')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('update preview ui', function() {
|
||||||
|
expect(insertPreview.updatePreviews).toHaveBeenCalledWith('src','selector')
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
describe('Intermediate step HTML', function() {
|
describe('Intermediate step HTML', function() {
|
||||||
|
|
||||||
var IntermediateHtmlStepUi = require('../../../examples/lib/intermediateHtmlStepUi');
|
var IntermediateHtmlStepUi = require('../examples/lib/intermediateHtmlStepUi')
|
||||||
var sequencer = require('../../../src/ImageSequencer')();
|
var sequencer = require('../src/ImageSequencer')()
|
||||||
var intermediateHtmlStepUi;
|
var intermediateHtmlStepUi;
|
||||||
|
|
||||||
beforeEach(()=>{
|
beforeEach(()=>{
|
||||||
intermediateHtmlStepUi = new IntermediateHtmlStepUi(sequencer);
|
intermediateHtmlStepUi = new IntermediateHtmlStepUi(sequencer)
|
||||||
|
|
||||||
spyOn(intermediateHtmlStepUi, 'insertStep');
|
spyOn(intermediateHtmlStepUi,'insertStep')
|
||||||
|
|
||||||
intermediateHtmlStepUi.insertStep();
|
intermediateHtmlStepUi.insertStep()
|
||||||
});
|
})
|
||||||
|
|
||||||
it('insert step ui', function() {
|
it('insert step ui', function() {
|
||||||
expect(intermediateHtmlStepUi.insertStep).toHaveBeenCalled();
|
expect(intermediateHtmlStepUi.insertStep).toHaveBeenCalled()
|
||||||
});
|
})
|
||||||
|
|
||||||
});
|
})
|
||||||
11
spec/support/jasmine.json
Normal file
11
spec/support/jasmine.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"spec_dir": "spec",
|
||||||
|
"spec_files": [
|
||||||
|
"**/*[sS]pec.js"
|
||||||
|
],
|
||||||
|
"helpers": [
|
||||||
|
"helpers/**/*.js"
|
||||||
|
],
|
||||||
|
"stopSpecOnExpectationFailure": false,
|
||||||
|
"random": true
|
||||||
|
}
|
||||||
@@ -1,40 +1,40 @@
|
|||||||
describe('URL manipulation methods', function() {
|
describe('URL manipulation methods', function() {
|
||||||
|
|
||||||
var UrlHash = require('../../../examples/lib/urlHash');
|
var UrlHash = require('../examples/lib/urlHash')
|
||||||
var urlHash;
|
var urlHash;
|
||||||
var params = {
|
var params = {
|
||||||
module: 'brightness',
|
module: 'brightness',
|
||||||
brightness: 50
|
brightness: 50
|
||||||
};
|
}
|
||||||
|
|
||||||
beforeEach(()=>{
|
beforeEach(()=>{
|
||||||
urlHash = UrlHash;
|
urlHash = UrlHash
|
||||||
|
|
||||||
spyOn(urlHash, 'getUrlHashParameters');
|
spyOn(urlHash,'getUrlHashParameters')
|
||||||
spyOn(urlHash, 'getUrlHashParameter');
|
spyOn(urlHash,'getUrlHashParameter')
|
||||||
spyOn(urlHash, 'setUrlHashParameters');
|
spyOn(urlHash,'setUrlHashParameters')
|
||||||
spyOn(urlHash, 'setUrlHashParameter');
|
spyOn(urlHash,'setUrlHashParameter')
|
||||||
|
|
||||||
urlHash.getUrlHashParameters();
|
urlHash.getUrlHashParameters()
|
||||||
urlHash.getUrlHashParameter('module');
|
urlHash.getUrlHashParameter('module')
|
||||||
urlHash.setUrlHashParameters(params);
|
urlHash.setUrlHashParameters(params)
|
||||||
urlHash.setUrlHashParameter('module', 'brightness');
|
urlHash.setUrlHashParameter('module','brightness')
|
||||||
});
|
})
|
||||||
|
|
||||||
it('gets url hash params from window hash', function() {
|
it('gets url hash params from window hash', function() {
|
||||||
expect(urlHash.getUrlHashParameters).toHaveBeenCalled();
|
expect(urlHash.getUrlHashParameters).toHaveBeenCalled()
|
||||||
});
|
})
|
||||||
|
|
||||||
it('gets url hash param from params object', function() {
|
it('gets url hash param from params object', function() {
|
||||||
expect(urlHash.getUrlHashParameter).toHaveBeenCalledWith('module');
|
expect(urlHash.getUrlHashParameter).toHaveBeenCalledWith('module')
|
||||||
});
|
})
|
||||||
|
|
||||||
it('accepts param object and sets url hash params', function() {
|
it('accepts param object and sets url hash params', function() {
|
||||||
expect(urlHash.setUrlHashParameters).toHaveBeenCalledWith(params);
|
expect(urlHash.setUrlHashParameters).toHaveBeenCalledWith(params)
|
||||||
});
|
})
|
||||||
|
|
||||||
it('accepts param key-value pair and sets url hash params', function() {
|
it('accepts param key-value pair and sets url hash params', function() {
|
||||||
expect(urlHash.setUrlHashParameter).toHaveBeenCalledWith('module', 'brightness');
|
expect(urlHash.setUrlHashParameter).toHaveBeenCalledWith('module','brightness')
|
||||||
});
|
})
|
||||||
|
|
||||||
});
|
})
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs')
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function checks if the directory exists, if not it creates one on the given path
|
* This function checks if the directory exists, if not it creates one on the given path
|
||||||
@@ -10,9 +10,9 @@ function makedir(path, callback){
|
|||||||
if(err) callback(err);
|
if(err) callback(err);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
else callback();
|
else callback()
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// Takes an array of steps and checks if they are valid steps for the sequencer.
|
// Takes an array of steps and checks if they are valid steps for the sequencer.
|
||||||
function validateSteps(steps, sequencer) {
|
function validateSteps(steps, sequencer) {
|
||||||
@@ -37,7 +37,7 @@ function validateConfig(config_, options_) {
|
|||||||
for (var input in options_) {
|
for (var input in options_) {
|
||||||
if (!config_[options_[input]]) {
|
if (!config_[options_[input]]) {
|
||||||
console.error(
|
console.error(
|
||||||
'\x1b[31m%s\x1b[0m',
|
"\x1b[31m%s\x1b[0m",
|
||||||
`Options Object does not have the required details "${
|
`Options Object does not have the required details "${
|
||||||
options_[input]
|
options_[input]
|
||||||
}" not specified. Fallback case activated`
|
}" not specified. Fallback case activated`
|
||||||
@@ -55,4 +55,4 @@ module.exports = exports = {
|
|||||||
makedir: makedir,
|
makedir: makedir,
|
||||||
validateSteps: validateSteps,
|
validateSteps: validateSteps,
|
||||||
validateConfig: validateConfig
|
validateConfig: validateConfig
|
||||||
};
|
}
|
||||||
@@ -2,7 +2,7 @@ var fs = require('fs');
|
|||||||
var getDirectories = function(rootDir, cb) {
|
var getDirectories = function(rootDir, cb) {
|
||||||
fs.readdir(rootDir, function(err, files) {
|
fs.readdir(rootDir, function(err, files) {
|
||||||
var dirs = [];
|
var dirs = [];
|
||||||
if (typeof (files) == 'undefined' || files.length == 0) {
|
if (typeof (files) == "undefined" || files.length == 0) {
|
||||||
cb(dirs);
|
cb(dirs);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -21,15 +21,15 @@ var getDirectories = function(rootDir, cb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = function ExportBin(dir = './output/', ref, basic, filename) {
|
module.exports = function ExportBin(dir = "./output/", ref, basic, filename) {
|
||||||
|
|
||||||
// If user did not give an output filename so we can continue without doing anything
|
// If user did not give an output filename so we can continue without doing anything
|
||||||
dir = (dir[dir.length - 1] == '/') ? dir : dir + '/';
|
dir = (dir[dir.length - 1] == "/") ? dir : dir + "/";
|
||||||
if (ref.options.inBrowser) return false;
|
if (ref.options.inBrowser) return false;
|
||||||
fs.access(dir, function(err) {
|
fs.access(dir, function(err) {
|
||||||
if (err) console.error(err);
|
if (err) console.error(err)
|
||||||
});
|
});
|
||||||
if (filename && basic) {
|
if (filename && basic) {
|
||||||
var steps = ref.steps;
|
var steps = ref.steps;
|
||||||
@@ -53,17 +53,17 @@ module.exports = function ExportBin(dir = './output/', ref, basic, filename) {
|
|||||||
var datauri = steps.slice(-1)[0].output.src;
|
var datauri = steps.slice(-1)[0].output.src;
|
||||||
var ext = steps.slice(-1)[0].output.format;
|
var ext = steps.slice(-1)[0].output.format;
|
||||||
var buffer = require('data-uri-to-buffer')(datauri);
|
var buffer = require('data-uri-to-buffer')(datauri);
|
||||||
fs.writeFile(root + 'image' + '_' + (steps.length - 1) + '.' + ext, buffer, function() { });
|
fs.writeFile(root + "image" + "_" + (steps.length - 1) + "." + ext, buffer, function() { });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (var i in steps) {
|
for (var i in steps) {
|
||||||
var datauri = steps[i].output.src;
|
var datauri = steps[i].output.src;
|
||||||
var ext = steps[i].output.format;
|
var ext = steps[i].output.format;
|
||||||
var buffer = require('data-uri-to-buffer')(datauri);
|
var buffer = require('data-uri-to-buffer')(datauri);
|
||||||
fs.writeFile(root + 'image' + '_' + i + '.' + ext, buffer, function() { });
|
fs.writeFile(root + "image" + "_" + i + "." + ext, buffer, function() { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
function objTypeOf(object){
|
function objTypeOf(object){
|
||||||
return Object.prototype.toString.call(object).split(' ')[1].slice(0, -1);
|
return Object.prototype.toString.call(object).split(" ")[1].slice(0,-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrimitive(object){
|
function getPrimitive(object){
|
||||||
@@ -7,13 +7,13 @@ function getPrimitive(object){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeArray(input) {
|
function makeArray(input) {
|
||||||
return (objTypeOf(input) == 'Array') ? input : [input];
|
return (objTypeOf(input)=="Array")?input:[input];
|
||||||
}
|
}
|
||||||
|
|
||||||
function copy(a) {
|
function copy(a) {
|
||||||
if (!typeof(a) == 'object') return a;
|
if (!typeof(a) == "object") return a;
|
||||||
if (objTypeOf(a) == 'Array') return a.slice();
|
if (objTypeOf(a) == "Array") return a.slice();
|
||||||
if (objTypeOf(a) == 'Object') {
|
if (objTypeOf(a) == "Object") {
|
||||||
var b = {};
|
var b = {};
|
||||||
for (var v in a) {
|
for (var v in a) {
|
||||||
b[v] = copy(a[v]);
|
b[v] = copy(a[v]);
|
||||||
@@ -26,58 +26,58 @@ function copy(a) {
|
|||||||
function formatInput(args,format,images) {
|
function formatInput(args,format,images) {
|
||||||
var json_q = {};
|
var json_q = {};
|
||||||
var format_i = format;
|
var format_i = format;
|
||||||
if (format == '+')
|
if (format == "+")
|
||||||
format = ['string_a', 'o_object'];
|
format = ['string_a', 'o_object'];
|
||||||
else if (format == '-')
|
else if (format == "-")
|
||||||
format = ['number_a'];
|
format = ['number_a'];
|
||||||
else if (format == '^')
|
else if (format == "^")
|
||||||
format = ['number', 'string', 'o_object'];
|
format = ['number', 'string', 'o_object'];
|
||||||
else if (format == 'r')
|
else if (format == "r")
|
||||||
format = ['o_number'];
|
format = ['o_number'];
|
||||||
else if (format == 'l')
|
else if (format == "l")
|
||||||
format = ['string','o_function'];
|
format = ['string','o_function'];
|
||||||
|
|
||||||
|
|
||||||
if(format[format.length - 1] == 'o_object') {
|
if(format[format.length-1] == "o_object") {
|
||||||
if(objTypeOf(args[args.length - 1]) != 'Object')
|
if(objTypeOf(args[args.length-1]) != "Object")
|
||||||
args.push({});
|
args.push({});
|
||||||
}
|
}
|
||||||
else if (format[format.length - 1] == 'o_number') {
|
else if (format[format.length-1] == "o_number") {
|
||||||
if(typeof(args[args.length - 1]) != 'number' && objTypeOf(args[0]) != 'Object')
|
if(typeof(args[args.length-1]) != "number" && objTypeOf(args[0])!="Object")
|
||||||
args.push(1);
|
args.push(1);
|
||||||
}
|
}
|
||||||
else if (format[format.length - 1] == 'o_function') {
|
else if (format[format.length-1] == "o_function") {
|
||||||
if(objTypeOf(args[args.length - 1]) != 'Function' && objTypeOf(args[0]) != 'Object')
|
if(objTypeOf(args[args.length-1]) != "Function" && objTypeOf(args[0])!="Object")
|
||||||
args.push(function(){});
|
args.push(function(){});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(args.length == format.length) {//making of arrays
|
if(args.length == format.length) {//making of arrays
|
||||||
for (var i in format) {
|
for (var i in format) {
|
||||||
if (format[i].substr(format[i].length - 2, 2) == '_a')
|
if (format[i].substr(format[i].length-2,2)=="_a")
|
||||||
args[i] = makeArray(args[i]);
|
args[i] = makeArray(args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length == 1 ) {
|
if (args.length == 1 ) {
|
||||||
if(format_i == 'r') json_q = {0:copy(args[0])};
|
if(format_i == "r") json_q = {0:copy(args[0])};
|
||||||
else if(format_i == '-') {
|
else if(format_i == "-") {
|
||||||
json_q=[];
|
json_q=[];
|
||||||
json_q= copy(args[0]);
|
json_q= copy(args[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (format_i == 'r' ) {
|
else if (format_i == "r" ) {
|
||||||
for (var img in args[0]) json_q = {0:args[0]};
|
for (var img in args[0]) json_q = {0:args[0]};
|
||||||
}
|
}
|
||||||
else if (format_i == 'l') {
|
else if (format_i == "l") {
|
||||||
json_q = {
|
json_q = {
|
||||||
image: args[0],
|
image: args[0],
|
||||||
callback: args[1]
|
callback: args[1]
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
json_q = [];
|
json_q = [];
|
||||||
if(format_i == '+') {
|
if(format_i == "+") {
|
||||||
for(var s in args[0]) {
|
for(var s in args[0]) {
|
||||||
json_q.push({
|
json_q.push({
|
||||||
name: args[0][s],
|
name: args[0][s],
|
||||||
@@ -87,7 +87,7 @@ function formatInput(args, format, images) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(format_i == '^') {
|
if(format_i == "^") {
|
||||||
var size = this.steps.length;
|
var size = this.steps.length;
|
||||||
var index = args[0];
|
var index = args[0];
|
||||||
index = (index==size)?index:index%size;
|
index = (index==size)?index:index%size;
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
if (typeof window !== 'undefined') { isBrowser = true; }
|
if (typeof window !== 'undefined') { isBrowser = true }
|
||||||
else { var isBrowser = false; }
|
else { var isBrowser = false }
|
||||||
require('./util/getStep.js');
|
require('./util/getStep.js');
|
||||||
|
|
||||||
ImageSequencer = function ImageSequencer(options) {
|
ImageSequencer = function ImageSequencer(options) {
|
||||||
|
|
||||||
var sequencer = (this.name == 'ImageSequencer') ? this : this.sequencer;
|
var sequencer = (this.name == "ImageSequencer") ? this : this.sequencer;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.inBrowser = options.inBrowser === undefined ? isBrowser : options.inBrowser;
|
options.inBrowser = options.inBrowser === undefined ? isBrowser : options.inBrowser;
|
||||||
options.sequencerCounter = 0;
|
options.sequencerCounter = 0;
|
||||||
|
|
||||||
function objTypeOf(object) {
|
function objTypeOf(object) {
|
||||||
return Object.prototype.toString.call(object).split(' ')[1].slice(0, -1);
|
return Object.prototype.toString.call(object).split(" ")[1].slice(0, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function log(color, msg) {
|
function log(color, msg) {
|
||||||
if (options.ui != 'none') {
|
if (options.ui != "none") {
|
||||||
if (arguments.length == 1) console.log(arguments[0]);
|
if (arguments.length == 1) console.log(arguments[0]);
|
||||||
else if (arguments.length == 2) console.log(color, msg);
|
else if (arguments.length == 2) console.log(color, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function copy(a) {
|
function copy(a) {
|
||||||
if (!typeof (a) == 'object') return a;
|
if (!typeof (a) == "object") return a;
|
||||||
if (objTypeOf(a) == 'Array') return a.slice();
|
if (objTypeOf(a) == "Array") return a.slice();
|
||||||
if (objTypeOf(a) == 'Object') {
|
if (objTypeOf(a) == "Object") {
|
||||||
var b = {};
|
var b = {};
|
||||||
for (var v in a) {
|
for (var v in a) {
|
||||||
b[v] = copy(a[v]);
|
b[v] = copy(a[v]);
|
||||||
@@ -33,7 +34,7 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeArray(input) {
|
function makeArray(input) {
|
||||||
return (objTypeOf(input) == 'Array') ? input : [input];
|
return (objTypeOf(input) == "Array") ? input : [input];
|
||||||
}
|
}
|
||||||
|
|
||||||
var image,
|
var image,
|
||||||
@@ -63,15 +64,15 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
// else if (options.imageUrl) loadImage(imageUrl);
|
// else if (options.imageUrl) loadImage(imageUrl);
|
||||||
|
|
||||||
function addSteps() {
|
function addSteps() {
|
||||||
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
|
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
|
||||||
var args = [];
|
var args = [];
|
||||||
var json_q = {};
|
var json_q = {};
|
||||||
for (var arg in arguments) { args.push(copy(arguments[arg])); }
|
for (var arg in arguments) { args.push(copy(arguments[arg])); }
|
||||||
json_q = formatInput.call(this_, args, '+');
|
json_q = formatInput.call(this_, args, "+");
|
||||||
|
|
||||||
inputlog.push({ method: 'addSteps', json_q: copy(json_q) });
|
inputlog.push({ method: "addSteps", json_q: copy(json_q) });
|
||||||
for (var j in json_q)
|
for (var j in json_q)
|
||||||
require('./AddStep')(this_, json_q[j].name, json_q[j].o);
|
require("./AddStep")(this_, json_q[j].name, json_q[j].o);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,31 +89,31 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
|
|
||||||
function removeSteps() {
|
function removeSteps() {
|
||||||
var indices;
|
var indices;
|
||||||
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
|
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
|
||||||
var args = [];
|
var args = [];
|
||||||
for (var arg in arguments) args.push(copy(arguments[arg]));
|
for (var arg in arguments) args.push(copy(arguments[arg]));
|
||||||
|
|
||||||
var json_q = formatInput.call(this_, args, '-');
|
var json_q = formatInput.call(this_, args, "-");
|
||||||
inputlog.push({ method: 'removeSteps', json_q: copy(json_q) });
|
inputlog.push({ method: "removeSteps", json_q: copy(json_q) });
|
||||||
|
|
||||||
indices = json_q.sort(function(a, b) { return b - a; });
|
indices = json_q.sort(function(a, b) { return b - a });
|
||||||
for (var i in indices)
|
for (var i in indices)
|
||||||
removeStep(this_, indices[i]);
|
removeStep(this_, indices[i]);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertSteps() {
|
function insertSteps() {
|
||||||
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
|
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
|
||||||
var args = [];
|
var args = []
|
||||||
for (var arg in arguments) args.push(arguments[arg]);
|
for (var arg in arguments) args.push(arguments[arg]);
|
||||||
|
|
||||||
var json_q = formatInput.call(this_, args, '^');
|
var json_q = formatInput.call(this_, args, "^");
|
||||||
inputlog.push({ method: 'insertSteps', json_q: copy(json_q) });
|
inputlog.push({ method: "insertSteps", json_q: copy(json_q) });
|
||||||
|
|
||||||
var details = json_q;
|
var details = json_q;
|
||||||
details = details.sort(function(a, b) { return b.index - a.index; });
|
details = details.sort(function(a, b) { return b.index - a.index });
|
||||||
for (var i in details)
|
for (var i in details)
|
||||||
require('./InsertStep')(this_, details[i].index, details[i].name, details[i].o);
|
require("./InsertStep")(this_, details[i].index, details[i].name, details[i].o);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,21 +124,21 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
config = config || { mode: 'no-arg' };
|
config = config || { mode: 'no-arg' };
|
||||||
if (config.index) index = config.index;
|
if (config.index) index = config.index;
|
||||||
|
|
||||||
if (config.mode != 'no-arg' && typeof config != 'function') {
|
if (config.mode != "no-arg" && typeof config != 'function') {
|
||||||
if (config.progressObj) progressObj = config.progressObj;
|
if (config.progressObj) progressObj = config.progressObj;
|
||||||
delete arguments['0'];
|
delete arguments['0'];
|
||||||
}
|
}
|
||||||
|
|
||||||
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
|
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
|
||||||
var args = [];
|
var args = [];
|
||||||
for (var arg in arguments) args.push(copy(arguments[arg]));
|
for (var arg in arguments) args.push(copy(arguments[arg]));
|
||||||
|
|
||||||
var callback = function() { };
|
var callback = function() { };
|
||||||
for (var arg in args)
|
for (var arg in args)
|
||||||
if (objTypeOf(args[arg]) == 'Function')
|
if (objTypeOf(args[arg]) == "Function")
|
||||||
callback = args.splice(arg, 1)[0]; //callback is formed
|
callback = args.splice(arg, 1)[0]; //callback is formed
|
||||||
|
|
||||||
var json_q = formatInput.call(this_, args, 'r');
|
var json_q = formatInput.call(this_, args, "r");
|
||||||
|
|
||||||
require('./Run')(this_, json_q, callback, index, progressObj);
|
require('./Run')(this_, json_q, callback, index, progressObj);
|
||||||
|
|
||||||
@@ -146,19 +147,19 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
|
|
||||||
function loadImages() {
|
function loadImages() {
|
||||||
var args = [];
|
var args = [];
|
||||||
var prevSteps = this.getSteps().slice(1).map(step=>step.options.name);
|
var prevSteps = this.getSteps().slice(1).map(step=>step.options.name)
|
||||||
var sequencer = this;
|
var sequencer = this;
|
||||||
sequencer.image = arguments[0];
|
sequencer.image = arguments[0];
|
||||||
for (var arg in arguments) args.push(copy(arguments[arg]));
|
for (var arg in arguments) args.push(copy(arguments[arg]));
|
||||||
var json_q = formatInput.call(this, args, 'l');
|
var json_q = formatInput.call(this, args, "l");
|
||||||
if(this.getSteps().length!=0){
|
if(this.getSteps().length!=0){
|
||||||
this.options.sequencerCounter = 0;
|
this.options.sequencerCounter = 0;
|
||||||
inputlog = [];
|
inputlog = [];
|
||||||
this.steps = [];
|
this.steps = [];
|
||||||
}
|
}
|
||||||
inputlog.push({ method: 'loadImages', json_q: copy(json_q) });
|
inputlog.push({ method: "loadImages", json_q: copy(json_q) });
|
||||||
var ret = {
|
var ret = {
|
||||||
name: 'ImageSequencer Wrapper',
|
name: "ImageSequencer Wrapper",
|
||||||
sequencer: this,
|
sequencer: this,
|
||||||
addSteps: this.addSteps,
|
addSteps: this.addSteps,
|
||||||
removeSteps: this.removeSteps,
|
removeSteps: this.removeSteps,
|
||||||
@@ -169,11 +170,11 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
};
|
};
|
||||||
function loadPrevSteps(ref){
|
function loadPrevSteps(ref){
|
||||||
if(prevSteps.length!=0){
|
if(prevSteps.length!=0){
|
||||||
ref.addSteps(prevSteps);
|
ref.addSteps(prevSteps)
|
||||||
prevSteps=[];
|
prevSteps=[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require('./ui/LoadImage')(sequencer, 'image', json_q.image, function() {
|
require('./ui/LoadImage')(sequencer, "image", json_q.image, function() {
|
||||||
loadPrevSteps(sequencer);
|
loadPrevSteps(sequencer);
|
||||||
json_q.callback.call(ret);
|
json_q.callback.call(ret);
|
||||||
});
|
});
|
||||||
@@ -197,11 +198,11 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
|
|
||||||
var exportBin = function(dir, basic, filename) {
|
var exportBin = function(dir, basic, filename) {
|
||||||
return require('./ExportBin')(dir, this, basic, filename);
|
return require('./ExportBin')(dir, this, basic, filename);
|
||||||
};
|
}
|
||||||
|
|
||||||
function modulesInfo(name) {
|
function modulesInfo(name) {
|
||||||
var modulesdata = {};
|
var modulesdata = {}
|
||||||
if (name == 'load-image') return {};
|
if (name == "load-image") return {};
|
||||||
if (arguments.length == 0) {
|
if (arguments.length == 0) {
|
||||||
for (var modulename in this.modules) {
|
for (var modulename in this.modules) {
|
||||||
modulesdata[modulename] = modules[modulename][1];
|
modulesdata[modulename] = modules[modulename][1];
|
||||||
@@ -220,6 +221,124 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
return modulesdata;
|
return modulesdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Genates a CLI string for the current sequence
|
||||||
|
function toCliString() {
|
||||||
|
var cliStringSteps = `"`, cliOptions = {};
|
||||||
|
for (var step in this.steps) {
|
||||||
|
var name = (typeof this.steps[step].options !== "undefined")? this.steps[step].options.name : this.steps[step].name
|
||||||
|
if (name !== "load-image"){
|
||||||
|
cliStringSteps += `${name} `;
|
||||||
|
}
|
||||||
|
for (var inp in modulesInfo(name).inputs) {
|
||||||
|
cliOptions[inp] = this.steps[step].options[inp];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cliStringSteps = cliStringSteps.substr(0, cliStringSteps.length - 1) + `"`;
|
||||||
|
return `sequencer -i [PATH] -s ${cliStringSteps} -d '${JSON.stringify(cliOptions)}'`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strigifies the current sequence
|
||||||
|
function toString(step) {
|
||||||
|
if (step) {
|
||||||
|
return stepToString(step);
|
||||||
|
} else {
|
||||||
|
return copy(this.steps.map(stepToString).slice(1).join(','));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stringifies one step of the sequence
|
||||||
|
function stepToString(step) {
|
||||||
|
var arg = (step.name)?step.name:step.options.name;
|
||||||
|
let inputs = modulesInfo(arg).inputs || {}, op = {};
|
||||||
|
|
||||||
|
for (let input in inputs) {
|
||||||
|
|
||||||
|
if (!!step.options[input] && step.options[input] != inputs[input].default) {
|
||||||
|
op[input] = step.options[input];
|
||||||
|
op[input] = encodeURIComponent(op[input]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var configurations = Object.keys(op).map(key => key + ':' + op[key]).join('|');
|
||||||
|
return `${arg}{${configurations}}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exports the current sequence as an array of JSON steps
|
||||||
|
function toJSON() {
|
||||||
|
return this.stringToJSON(this.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coverts stringified sequence into an array of JSON steps
|
||||||
|
function stringToJSON(str) {
|
||||||
|
let steps;
|
||||||
|
if (str.includes(','))
|
||||||
|
steps = str.split(',');
|
||||||
|
else
|
||||||
|
steps = [str];
|
||||||
|
return steps.map(stringToJSONstep);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts one stringified step into JSON
|
||||||
|
function stringToJSONstep(str) {
|
||||||
|
var bracesStrings;
|
||||||
|
if (str.includes('{'))
|
||||||
|
if (str.includes('(') && str.indexOf('(') < str.indexOf('{'))
|
||||||
|
bracesStrings = ['(', ')'];
|
||||||
|
else
|
||||||
|
bracesStrings = ['{', '}'];
|
||||||
|
else
|
||||||
|
bracesStrings = ['(', ')'];
|
||||||
|
|
||||||
|
if (str.indexOf(bracesStrings[0]) === -1) { // if there are no settings specified
|
||||||
|
var moduleName = str.substr(0);
|
||||||
|
stepSettings = "";
|
||||||
|
} else {
|
||||||
|
var moduleName = str.substr(0, str.indexOf(bracesStrings[0]));
|
||||||
|
stepSettings = str.slice(str.indexOf(bracesStrings[0]) + 1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
stepSettings = stepSettings.split('|').reduce(function formatSettings(accumulator, current, i) {
|
||||||
|
var settingName = current.substr(0, current.indexOf(':')),
|
||||||
|
settingValue = current.substr(current.indexOf(':') + 1);
|
||||||
|
settingValue = settingValue.replace(/^\(/, '').replace(/\)$/, ''); // strip () at start/end
|
||||||
|
settingValue = settingValue.replace(/^\{/, '').replace(/\}$/, ''); // strip {} at start/end
|
||||||
|
settingValue = decodeURIComponent(settingValue);
|
||||||
|
current = [
|
||||||
|
settingName,
|
||||||
|
settingValue
|
||||||
|
];
|
||||||
|
if (!!settingName) accumulator[settingName] = settingValue;
|
||||||
|
return accumulator;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: moduleName,
|
||||||
|
options: stepSettings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// imports a string into the sequencer steps
|
||||||
|
function importString(str) {
|
||||||
|
let sequencer = this;
|
||||||
|
if (this.name != "ImageSequencer")
|
||||||
|
sequencer = this.sequencer;
|
||||||
|
var stepsFromString = stringToJSON(str);
|
||||||
|
stepsFromString.forEach(function eachStep(stepObj) {
|
||||||
|
sequencer.addSteps(stepObj.name, stepObj.options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// imports a array of JSON steps into the sequencer steps
|
||||||
|
function importJSON(obj) {
|
||||||
|
let sequencer = this;
|
||||||
|
if (this.name != "ImageSequencer")
|
||||||
|
sequencer = this.sequencer;
|
||||||
|
obj.forEach(function eachStep(stepObj) {
|
||||||
|
sequencer.addSteps(stepObj.name, stepObj.options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function loadNewModule(name, options) {
|
function loadNewModule(name, options) {
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
@@ -252,7 +371,7 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var mods = fs.readFileSync('./src/Modules.js').toString();
|
var mods = fs.readFileSync('./src/Modules.js').toString();
|
||||||
mods = mods.substr(0, mods.length - 1) + ' \'' + name + '\': require(\'' + path + '\'),\n}';
|
mods = mods.substr(0, mods.length - 1) + " '" + name + "': require('" + path + "'),\n}";
|
||||||
fs.writeFileSync('./src/Modules.js', mods);
|
fs.writeFileSync('./src/Modules.js', mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,11 +401,9 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
this.sequences = require('./SavedSequences.json');
|
this.sequences = require('./SavedSequences.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
var str = require('./Strings.js')(this.steps, modulesInfo, addSteps, copy);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
//literals and objects
|
//literals and objects
|
||||||
name: 'ImageSequencer',
|
name: "ImageSequencer",
|
||||||
options: options,
|
options: options,
|
||||||
inputlog: inputlog,
|
inputlog: inputlog,
|
||||||
modules: modules,
|
modules: modules,
|
||||||
@@ -306,17 +423,14 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
setUI: setUI,
|
setUI: setUI,
|
||||||
exportBin: exportBin,
|
exportBin: exportBin,
|
||||||
modulesInfo: modulesInfo,
|
modulesInfo: modulesInfo,
|
||||||
toCliString: str.toCliString,
|
toCliString: toCliString,
|
||||||
detectStringSyntax: str.detectStringSyntax,
|
toString: toString,
|
||||||
parseStringSyntax: str.parseStringSyntax,
|
stepToString: stepToString,
|
||||||
stringToSteps: str.stringToSteps,
|
toJSON: toJSON,
|
||||||
toString: str.toString,
|
stringToJSON: stringToJSON,
|
||||||
stepToString: str.stepToString,
|
stringToJSONstep: stringToJSONstep,
|
||||||
toJSON: str.toJSON,
|
importString: importString,
|
||||||
stringToJSON: str.stringToJSON,
|
importJSON: importJSON,
|
||||||
stringToJSONstep: str.stringToJSONstep,
|
|
||||||
importString: str.importString,
|
|
||||||
importJSON: str.importJSON,
|
|
||||||
loadNewModule: loadNewModule,
|
loadNewModule: loadNewModule,
|
||||||
saveNewModule: saveNewModule,
|
saveNewModule: saveNewModule,
|
||||||
createMetaModule: require('./util/createMetaModule'),
|
createMetaModule: require('./util/createMetaModule'),
|
||||||
@@ -330,7 +444,7 @@ ImageSequencer = function ImageSequencer(options) {
|
|||||||
copy: copy,
|
copy: copy,
|
||||||
|
|
||||||
setInputStep: require('./ui/SetInputStep')(sequencer)
|
setInputStep: require('./ui/SetInputStep')(sequencer)
|
||||||
};
|
}
|
||||||
|
|
||||||
};
|
}
|
||||||
module.exports = ImageSequencer;
|
module.exports = ImageSequencer;
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ function InsertStep(ref, index, name, o) {
|
|||||||
return ref.importJSON(ref.sequences[name]);
|
return ref.importJSON(ref.sequences[name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ref.detectStringSyntax(name)) {
|
|
||||||
return ref.stringToSteps(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function insertStep(index, name, o_) {
|
function insertStep(index, name, o_) {
|
||||||
if (ref.modules[name]) var moduleInfo = ref.modules[name][1];
|
if (ref.modules[name]) var moduleInfo = ref.modules[name][1];
|
||||||
@@ -21,17 +18,15 @@ function InsertStep(ref, index, name, o) {
|
|||||||
o.number = ref.options.sequencerCounter++; //Gives a Unique ID to each step
|
o.number = ref.options.sequencerCounter++; //Gives a Unique ID to each step
|
||||||
o.name = o_.name || name || moduleInfo.name;
|
o.name = o_.name || name || moduleInfo.name;
|
||||||
o.description = o_.description || moduleInfo.description;
|
o.description = o_.description || moduleInfo.description;
|
||||||
o.moduleInfo = o_.moduleInfo || moduleInfo;
|
|
||||||
o.selector = o_.selector || 'ismod-' + name;
|
o.selector = o_.selector || 'ismod-' + name;
|
||||||
o.container = o_.container || ref.options.selector;
|
o.container = o_.container || ref.options.selector;
|
||||||
o.inBrowser = ref.options.inBrowser;
|
o.inBrowser = ref.options.inBrowser;
|
||||||
o.useWasm = (ref.options.useWasm === false) ? false : true;
|
|
||||||
if (index == -1) index = ref.steps.length;
|
if (index == -1) index = ref.steps.length;
|
||||||
|
|
||||||
o.step = {
|
o.step = {
|
||||||
name: o.name,
|
name: o.name,
|
||||||
description: o.description,
|
description: o.description,
|
||||||
moduleInfo: o.moduleInfo,
|
|
||||||
ID: o.number,
|
ID: o.number,
|
||||||
inBrowser: ref.options.inBrowser,
|
inBrowser: ref.options.inBrowser,
|
||||||
ui: ref.options.ui,
|
ui: ref.options.ui,
|
||||||
@@ -45,7 +40,7 @@ function InsertStep(ref, index, name, o) {
|
|||||||
let step = stepsArray[i];
|
let step = stepsArray[i];
|
||||||
ref.insertSteps(index + Number.parseInt(i), step['name'], step['options']);
|
ref.insertSteps(index + Number.parseInt(i), step['name'], step['options']);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// Tell UI that a step has been set up.
|
// Tell UI that a step has been set up.
|
||||||
o = o || {};
|
o = o || {};
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ module.exports = {
|
|||||||
'add-qr': require('./modules/AddQR'),
|
'add-qr': require('./modules/AddQR'),
|
||||||
'average': require('./modules/Average'),
|
'average': require('./modules/Average'),
|
||||||
'blend': require('./modules/Blend'),
|
'blend': require('./modules/Blend'),
|
||||||
'blob-analysis': require('./modules/BlobAnalysis'),
|
|
||||||
'blur': require('./modules/Blur'),
|
'blur': require('./modules/Blur'),
|
||||||
'brightness': require('./modules/Brightness'),
|
'brightness': require('./modules/Brightness'),
|
||||||
'canvas-resize': require('./modules/CanvasResize'),
|
'canvas-resize': require('./modules/CanvasResize'),
|
||||||
@@ -29,14 +28,11 @@ module.exports = {
|
|||||||
'gradient': require('./modules/Gradient'),
|
'gradient': require('./modules/Gradient'),
|
||||||
'grid-overlay': require('./modules/GridOverlay'),
|
'grid-overlay': require('./modules/GridOverlay'),
|
||||||
'import-image': require('./modules/ImportImage'),
|
'import-image': require('./modules/ImportImage'),
|
||||||
'minify-image': require('./modules/MinifyImage'),
|
|
||||||
'invert': require('image-sequencer-invert'),
|
'invert': require('image-sequencer-invert'),
|
||||||
'matcher': require('./modules/Matcher'),
|
|
||||||
'ndvi': require('./modules/Ndvi'),
|
'ndvi': require('./modules/Ndvi'),
|
||||||
'ndvi-colormap': require('./modules/NdviColormap'),
|
'ndvi-colormap': require('./modules/NdviColormap'),
|
||||||
'noise-reduction': require('./modules/NoiseReduction'),
|
|
||||||
'overlay': require('./modules/Overlay'),
|
|
||||||
'paint-bucket': require('./modules/PaintBucket'),
|
'paint-bucket': require('./modules/PaintBucket'),
|
||||||
|
'overlay': require('./modules/Overlay'),
|
||||||
'replace-color': require('./modules/ReplaceColor'),
|
'replace-color': require('./modules/ReplaceColor'),
|
||||||
'resize': require('./modules/Resize'),
|
'resize': require('./modules/Resize'),
|
||||||
'rotate': require('./modules/Rotate'),
|
'rotate': require('./modules/Rotate'),
|
||||||
@@ -44,6 +40,5 @@ module.exports = {
|
|||||||
'text-overlay': require('./modules/TextOverlay'),
|
'text-overlay': require('./modules/TextOverlay'),
|
||||||
'threshold': require('./modules/Threshold'),
|
'threshold': require('./modules/Threshold'),
|
||||||
'tint': require('./modules/Tint'),
|
'tint': require('./modules/Tint'),
|
||||||
'webgl-distort': require('./modules/WebglDistort'),
|
|
||||||
'white-balance': require('./modules/WhiteBalance')
|
'white-balance': require('./modules/WhiteBalance')
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -33,20 +33,16 @@ function ReplaceImage(ref, selector, steps, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var base64 = btoa(raw);
|
var base64 = btoa(raw);
|
||||||
var dataURL = 'data:image/' + ext + ';base64,' + base64;
|
var dataURL="data:image/"+ext+";base64," + base64;
|
||||||
make(dataURL);
|
make(dataURL);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(url.substr(0, 11).toLowerCase() != 'data:image/') xmlHTTP.send();
|
if(url.substr(0,11).toLowerCase()!="data:image/") xmlHTTP.send();
|
||||||
else make(url);
|
else make(url);
|
||||||
|
|
||||||
function make(url) {
|
function make(url) {
|
||||||
tempSequencer.loadImage(url, function(){
|
tempSequencer.loadImage(url, function(){
|
||||||
// this.addSteps(steps).run({stop:function(){}},function(out){
|
this.addSteps(steps).run({stop:function(){}},function(out){
|
||||||
var sequence = this.addSteps(steps);
|
|
||||||
if (ref.detectStringSyntax(steps))
|
|
||||||
sequence = this.stringToSteps(steps);
|
|
||||||
sequence.run({stop:function(){}}, function(out){
|
|
||||||
img.src = out;
|
img.src = out;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ function Run(ref, json_q, callback, ind, progressObj) {
|
|||||||
|
|
||||||
function drawStep(drawarray, pos) {
|
function drawStep(drawarray, pos) {
|
||||||
if (pos == drawarray.length && drawarray[pos - 1] !== undefined) {
|
if (pos == drawarray.length && drawarray[pos - 1] !== undefined) {
|
||||||
if (ref.objTypeOf(callback) == 'Function' && ref.steps.slice(-1)[0].output) {
|
if (ref.objTypeOf(callback) == "Function" && ref.steps.slice(-1)[0].output) {
|
||||||
var steps = ref.steps;
|
var steps = ref.steps;
|
||||||
var out = steps[steps.length - 1].output.src;
|
var out = steps[steps.length - 1].output.src;
|
||||||
callback(out);
|
callback(out);
|
||||||
@@ -25,7 +25,7 @@ function Run(ref, json_q, callback, ind, progressObj) {
|
|||||||
};
|
};
|
||||||
step.getIndex = function getIndex() {
|
step.getIndex = function getIndex() {
|
||||||
return i;
|
return i;
|
||||||
};
|
}
|
||||||
|
|
||||||
for (var util in getStepUtils) {
|
for (var util in getStepUtils) {
|
||||||
if (getStepUtils.hasOwnProperty(util)) {
|
if (getStepUtils.hasOwnProperty(util)) {
|
||||||
@@ -73,8 +73,8 @@ function Run(ref, json_q, callback, ind, progressObj) {
|
|||||||
else if (json_q[0] == 0) json_q[0]++;
|
else if (json_q[0] == 0) json_q[0]++;
|
||||||
var prevstep = ref.steps[json_q[0] - 1];
|
var prevstep = ref.steps[json_q[0] - 1];
|
||||||
while (
|
while (
|
||||||
typeof prevstep == 'undefined' ||
|
typeof prevstep == "undefined" ||
|
||||||
typeof prevstep.output == 'undefined'
|
typeof prevstep.output == "undefined"
|
||||||
) {
|
) {
|
||||||
prevstep = ref.steps[--json_q[0] - 1];
|
prevstep = ref.steps[--json_q[0] - 1];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ module.exports = function(input) {
|
|||||||
input.dataUriToBuffer = dataUriToBuffer;
|
input.dataUriToBuffer = dataUriToBuffer;
|
||||||
input.savePixels = savePixels;
|
input.savePixels = savePixels;
|
||||||
return input;
|
return input;
|
||||||
};
|
}
|
||||||
159
src/Strings.js
159
src/Strings.js
@@ -1,159 +0,0 @@
|
|||||||
module.exports = function(steps, modulesInfo, addSteps, copy) {
|
|
||||||
// Genates a CLI string for the current sequence
|
|
||||||
function toCliString() {
|
|
||||||
var cliStringSteps = '"', cliOptions = {};
|
|
||||||
for (var step in this.steps) {
|
|
||||||
var name = (typeof this.steps[step].options !== 'undefined') ? this.steps[step].options.name : this.steps[step].name;
|
|
||||||
if (name !== 'load-image'){
|
|
||||||
cliStringSteps += `${name} `;
|
|
||||||
}
|
|
||||||
for (var inp in modulesInfo(name).inputs) {
|
|
||||||
cliOptions[inp] = this.steps[step].options[inp];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cliStringSteps = cliStringSteps.substr(0, cliStringSteps.length - 1) + '"';
|
|
||||||
return `sequencer -i [PATH] -s ${cliStringSteps} -d '${JSON.stringify(cliOptions)}'`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if input is a string of comma separated module names
|
|
||||||
function detectStringSyntax(str) {
|
|
||||||
let result = (str.includes(',') || str.includes('{')) ? true : false;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses input string and returns array of module names
|
|
||||||
function parseStringSyntax(str) {
|
|
||||||
let stringifiedNames = str.replace(/\s/g, '');
|
|
||||||
let moduleNames = stringifiedNames.split(',');
|
|
||||||
return moduleNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
// imports string of comma separated module names to sequencer steps
|
|
||||||
function stringToSteps(str) {
|
|
||||||
let sequencer = this;
|
|
||||||
let names = [];
|
|
||||||
if (this.name != 'ImageSequencer')
|
|
||||||
sequencer = this.sequencer;
|
|
||||||
if (detectStringSyntax(str))
|
|
||||||
names = stringToJSON(str);
|
|
||||||
names.forEach(function eachStep(stepObj) {
|
|
||||||
sequencer.addSteps(stepObj.name, stepObj.options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strigifies the current sequence
|
|
||||||
function toString(step) {
|
|
||||||
if (step) {
|
|
||||||
return stepToString(step);
|
|
||||||
} else {
|
|
||||||
return copy(this.steps.map(stepToString).slice(1).join(','));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stringifies one step of the sequence
|
|
||||||
function stepToString(step) {
|
|
||||||
var arg = (step.name) ? step.name : step.options.name;
|
|
||||||
let inputs = modulesInfo(arg).inputs || {}, op = {};
|
|
||||||
|
|
||||||
for (let input in inputs) {
|
|
||||||
|
|
||||||
if (!!step.options[input] && step.options[input] != inputs[input].default) {
|
|
||||||
op[input] = step.options[input];
|
|
||||||
op[input] = encodeURIComponent(op[input]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var configurations = Object.keys(op).map(key => key + ':' + op[key]).join('|');
|
|
||||||
return `${arg}{${configurations}}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// exports the current sequence as an array of JSON steps
|
|
||||||
function toJSON() {
|
|
||||||
return this.stringToJSON(this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coverts stringified sequence into an array of JSON steps
|
|
||||||
function stringToJSON(str) {
|
|
||||||
let steps;
|
|
||||||
if (detectStringSyntax(str))
|
|
||||||
steps = parseStringSyntax(str);
|
|
||||||
else
|
|
||||||
steps = [str];
|
|
||||||
return steps.map(stringToJSONstep);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts one stringified step into JSON
|
|
||||||
function stringToJSONstep(str) {
|
|
||||||
var bracesStrings;
|
|
||||||
if (str.includes('{'))
|
|
||||||
if (str.includes('(') && str.indexOf('(') < str.indexOf('{'))
|
|
||||||
bracesStrings = ['(', ')'];
|
|
||||||
else
|
|
||||||
bracesStrings = ['{', '}'];
|
|
||||||
else
|
|
||||||
bracesStrings = ['(', ')'];
|
|
||||||
|
|
||||||
if (str.indexOf(bracesStrings[0]) === -1) { // if there are no settings specified
|
|
||||||
var moduleName = str.substr(0);
|
|
||||||
stepSettings = '';
|
|
||||||
} else {
|
|
||||||
var moduleName = str.substr(0, str.indexOf(bracesStrings[0]));
|
|
||||||
stepSettings = str.slice(str.indexOf(bracesStrings[0]) + 1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
stepSettings = stepSettings.split('|').reduce(function formatSettings(accumulator, current, i) {
|
|
||||||
var settingName = current.substr(0, current.indexOf(':')),
|
|
||||||
settingValue = current.substr(current.indexOf(':') + 1);
|
|
||||||
settingValue = settingValue.replace(/^\(/, ''); // strip () at start/end
|
|
||||||
settingValue = settingValue.replace(/^\{/, '').replace(/\}$/, ''); // strip {} at start/end
|
|
||||||
settingValue = decodeURIComponent(settingValue);
|
|
||||||
current = [
|
|
||||||
settingName,
|
|
||||||
settingValue
|
|
||||||
];
|
|
||||||
if (settingName) accumulator[settingName] = settingValue;
|
|
||||||
return accumulator;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: moduleName,
|
|
||||||
options: stepSettings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// imports a string into the sequencer steps
|
|
||||||
function importString(str) {
|
|
||||||
let sequencer = this;
|
|
||||||
if (this.name != 'ImageSequencer')
|
|
||||||
sequencer = this.sequencer;
|
|
||||||
var stepsFromString = stringToJSON(str);
|
|
||||||
stepsFromString.forEach(function eachStep(stepObj) {
|
|
||||||
sequencer.addSteps(stepObj.name, stepObj.options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// imports a array of JSON steps into the sequencer steps
|
|
||||||
function importJSON(obj) {
|
|
||||||
let sequencer = this;
|
|
||||||
if (this.name != 'ImageSequencer')
|
|
||||||
sequencer = this.sequencer;
|
|
||||||
obj.forEach(function eachStep(stepObj) {
|
|
||||||
sequencer.addSteps(stepObj.name, stepObj.options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
toCliString: toCliString,
|
|
||||||
detectStringSyntax: detectStringSyntax,
|
|
||||||
parseStringSyntax: parseStringSyntax,
|
|
||||||
stringToSteps: stringToSteps,
|
|
||||||
toString: toString,
|
|
||||||
stepToString: stepToString,
|
|
||||||
toJSON: toJSON,
|
|
||||||
stringToJSON: stringToJSON,
|
|
||||||
stringToJSONstep: stringToJSONstep,
|
|
||||||
importString: importString,
|
|
||||||
importJSON: importJSON
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
var childProcess = require('child_process');
|
var childProcess = require('child_process')
|
||||||
var Spinner = require('ora');
|
var Spinner = require('ora');
|
||||||
|
|
||||||
module.exports = function (program, sequencer) {
|
module.exports = function (program, sequencer) {
|
||||||
console.log(
|
console.log(
|
||||||
'\x1b[33m%s\x1b[0m',
|
"\x1b[33m%s\x1b[0m",
|
||||||
'Please wait while your Module is being Installed...\nThis may take a while!'
|
"Please wait while your Module is being Installed...\nThis may take a while!"
|
||||||
);
|
);
|
||||||
|
|
||||||
var params = program.installModule.split(' ');
|
var params = program.installModule.split(' ');
|
||||||
var spinner = Spinner('Now Installing...').start();
|
var spinner = Spinner("Now Installing...").start();
|
||||||
childProcess.execSync(`npm i ${params[1]}`);
|
childProcess.execSync(`npm i ${params[1]}`)
|
||||||
sequencer.saveNewModule(params[0], params[1]);
|
sequencer.saveNewModule(params[0], params[1]);
|
||||||
sequencer.loadNewModule(params[0], require(params[1]));
|
sequencer.loadNewModule(params[0], require(params[1]));
|
||||||
spinner.stop();
|
spinner.stop();
|
||||||
console.log('\x1b[32m%s\x1b[0m', 'Your module was installed successfully!!');
|
console.log("\x1b[32m%s\x1b[0m", "Your module was installed successfully!!");
|
||||||
};
|
}
|
||||||
@@ -2,6 +2,6 @@ module.exports = function (program, sequencer) {
|
|||||||
|
|
||||||
var params = program.saveSequence.split(' ');
|
var params = program.saveSequence.split(' ');
|
||||||
sequencer.saveSequence(params[0], params[1]);
|
sequencer.saveSequence(params[0], params[1]);
|
||||||
console.log('\x1b[32m', 'Your sequence was saved successfully!!');
|
console.log("\x1b[32m", "Your sequence was saved successfully!!");
|
||||||
|
|
||||||
};
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
var Spinner = require('ora');
|
var Spinner = require('ora');
|
||||||
var readlineSync = require('readline-sync');
|
var readlineSync = require('readline-sync');
|
||||||
var utils = require('../CliUtils');
|
var utils = require('../CliUtils')
|
||||||
|
|
||||||
module.exports = function (program, sequencer, outputFilename) {
|
module.exports = function (program, sequencer, outputFilename) {
|
||||||
utils.makedir(program.output, () => {
|
utils.makedir(program.output, () => {
|
||||||
console.log('Files will be exported to "' + program.output + '"');
|
console.log('Files will be exported to "' + program.output + '"');
|
||||||
|
|
||||||
if (program.basic)
|
if (program.basic)
|
||||||
console.log('Basic mode is enabled, outputting only final image');
|
console.log("Basic mode is enabled, outputting only final image");
|
||||||
|
|
||||||
// Iterate through the steps and retrieve their inputs.
|
// Iterate through the steps and retrieve their inputs.
|
||||||
program.step.forEach(function(step) {
|
program.step.forEach(function(step) {
|
||||||
@@ -15,7 +15,7 @@ module.exports = function (program, sequencer, outputFilename) {
|
|||||||
|
|
||||||
// If inputs exists, print to console.
|
// If inputs exists, print to console.
|
||||||
if (Object.keys(options).length) {
|
if (Object.keys(options).length) {
|
||||||
console.log('[' + step + ']: Inputs');
|
console.log("[" + step + "]: Inputs");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If inputs exists, print them out with descriptions.
|
// If inputs exists, print them out with descriptions.
|
||||||
@@ -23,9 +23,9 @@ module.exports = function (program, sequencer, outputFilename) {
|
|||||||
// The array below creates a variable number of spaces. This is done with (length + 1).
|
// The array below creates a variable number of spaces. This is done with (length + 1).
|
||||||
// The extra 4 that makes it (length + 5) is to account for the []: characters
|
// The extra 4 that makes it (length + 5) is to account for the []: characters
|
||||||
console.log(
|
console.log(
|
||||||
new Array(step.length + 5).join(' ') +
|
new Array(step.length + 5).join(" ") +
|
||||||
input +
|
input +
|
||||||
': ' +
|
": " +
|
||||||
options[input].desc
|
options[input].desc
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -33,18 +33,18 @@ module.exports = function (program, sequencer, outputFilename) {
|
|||||||
if (program.config) {
|
if (program.config) {
|
||||||
try {
|
try {
|
||||||
var config = JSON.parse(program.config);
|
var config = JSON.parse(program.config);
|
||||||
console.log('The parsed options object: ', config);
|
console.log(`The parsed options object: `, config);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(
|
console.error(
|
||||||
'\x1b[31m%s\x1b[0m',
|
"\x1b[31m%s\x1b[0m",
|
||||||
'Options(Config) is not a not valid JSON Fallback activate'
|
`Options(Config) is not a not valid JSON Fallback activate`
|
||||||
);
|
);
|
||||||
program.config = false;
|
program.config = false;
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (program.config && utils.validateConfig(config, options)) {
|
if (program.config && utils.validateConfig(config, options)) {
|
||||||
console.log('Now using Options object');
|
console.log("Now using Options object");
|
||||||
Object.keys(options).forEach(function(input) {
|
Object.keys(options).forEach(function(input) {
|
||||||
options[input] = config[input];
|
options[input] = config[input];
|
||||||
});
|
});
|
||||||
@@ -52,15 +52,15 @@ module.exports = function (program, sequencer, outputFilename) {
|
|||||||
// If inputs exist, iterate through them and prompt for values.
|
// If inputs exist, iterate through them and prompt for values.
|
||||||
Object.keys(options).forEach(function(input) {
|
Object.keys(options).forEach(function(input) {
|
||||||
var value = readlineSync.question(
|
var value = readlineSync.question(
|
||||||
'[' +
|
"[" +
|
||||||
step +
|
step +
|
||||||
']: Enter a value for ' +
|
"]: Enter a value for " +
|
||||||
input +
|
input +
|
||||||
' (' +
|
" (" +
|
||||||
options[input].type +
|
options[input].type +
|
||||||
', default: ' +
|
", default: " +
|
||||||
options[input].default +
|
options[input].default +
|
||||||
'): '
|
"): "
|
||||||
);
|
);
|
||||||
options[input] = value;
|
options[input] = value;
|
||||||
});
|
});
|
||||||
@@ -71,7 +71,7 @@ module.exports = function (program, sequencer, outputFilename) {
|
|||||||
|
|
||||||
var spinnerObj = { succeed: () => { }, stop: () => { } };
|
var spinnerObj = { succeed: () => { }, stop: () => { } };
|
||||||
if (!process.env.TEST)
|
if (!process.env.TEST)
|
||||||
spinnerObj = Spinner('Your Image is being processed..').start();
|
spinnerObj = Spinner("Your Image is being processed..").start();
|
||||||
|
|
||||||
// Run the sequencer.
|
// Run the sequencer.
|
||||||
sequencer.run({ progressObj: spinnerObj }, function() {
|
sequencer.run({ progressObj: spinnerObj }, function() {
|
||||||
@@ -81,8 +81,8 @@ module.exports = function (program, sequencer, outputFilename) {
|
|||||||
//check if spinner was not overriden stop it
|
//check if spinner was not overriden stop it
|
||||||
if (!spinnerObj.overrideFlag) {
|
if (!spinnerObj.overrideFlag) {
|
||||||
spinnerObj.succeed();
|
spinnerObj.succeed();
|
||||||
console.log('\nDone!!');
|
console.log(`\nDone!!`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
@@ -2,7 +2,7 @@ module.exports = function AddQR(options, UI) {
|
|||||||
|
|
||||||
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
||||||
options.size = options.size || defaults.size;
|
options.size = options.size || defaults.size;
|
||||||
options.qrCodeString = options.qrCodeString || 'https://github.com/publiclab/image-sequencer';
|
options.qrCodeString = options.qrCodeString || "https://github.com/publiclab/image-sequencer";
|
||||||
var output;
|
var output;
|
||||||
getPixels = require('get-pixels');
|
getPixels = require('get-pixels');
|
||||||
|
|
||||||
@@ -28,18 +28,17 @@ module.exports = function AddQR(options, UI) {
|
|||||||
function output(image, datauri, mimetype) {
|
function output(image, datauri, mimetype) {
|
||||||
step.output = { src: datauri, format: mimetype };
|
step.output = { src: datauri, format: mimetype };
|
||||||
}
|
}
|
||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
changePixel: changePixel,
|
changePixel: changePixel,
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,5 +47,5 @@ module.exports = function AddQR(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
module.exports = exports = function (options, pixels, oldPixels, callback) {
|
module.exports = exports = function (options, pixels, oldPixels, callback) {
|
||||||
var QRCode = require('qrcode');
|
var QRCode = require('qrcode')
|
||||||
QRCode.toDataURL(options.qrCodeString, function (err, url) {
|
QRCode.toDataURL(options.qrCodeString, function (err, url) {
|
||||||
var getPixels = require('get-pixels');
|
var getPixels = require("get-pixels");
|
||||||
getPixels(url, function (err, qrPixels) {
|
getPixels(url, function (err, qrPixels) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('Bad image path', image);
|
console.log("Bad image path", image);
|
||||||
}
|
}
|
||||||
|
|
||||||
var imagejs = require('imagejs');
|
var imagejs = require('imagejs');
|
||||||
@@ -12,7 +12,7 @@ module.exports = exports = function (options, pixels, oldPixels, callback) {
|
|||||||
bitmap._data.data = qrPixels.data;
|
bitmap._data.data = qrPixels.data;
|
||||||
var resized = bitmap.resize({
|
var resized = bitmap.resize({
|
||||||
width: options.size, height: options.size,
|
width: options.size, height: options.size,
|
||||||
algorithm: 'bicubicInterpolation'
|
algorithm: "bicubicInterpolation"
|
||||||
});
|
});
|
||||||
|
|
||||||
qrPixels.data = resized._data.data;
|
qrPixels.data = resized._data.data;
|
||||||
@@ -26,23 +26,23 @@ module.exports = exports = function (options, pixels, oldPixels, callback) {
|
|||||||
for (var m = 0; m < width; m++) {
|
for (var m = 0; m < width; m++) {
|
||||||
for (var n = 0; n < height; n++) {
|
for (var n = 0; n < height; n++) {
|
||||||
if (m >= xe && n >= ye) {
|
if (m >= xe && n >= ye) {
|
||||||
pixels.set(m, n, 0, qrPixels.get(m - xe, n - ye, 0));
|
pixels.set(m, n, 0, qrPixels.get(m - xe, n - ye, 0))
|
||||||
pixels.set(m, n, 1, qrPixels.get(m - xe, n - ye, 1));
|
pixels.set(m, n, 1, qrPixels.get(m - xe, n - ye, 1))
|
||||||
pixels.set(m, n, 2, qrPixels.get(m - xe, n - ye, 2));
|
pixels.set(m, n, 2, qrPixels.get(m - xe, n - ye, 2))
|
||||||
pixels.set(m, n, 3, qrPixels.get(m - xe, n - ye, 3));
|
pixels.set(m, n, 3, qrPixels.get(m - xe, n - ye, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
pixels.set(m, n, 0, oldPixels.get(m, n, 0));
|
pixels.set(m, n, 0, oldPixels.get(m, n, 0))
|
||||||
pixels.set(m, n, 1, oldPixels.get(m, n, 1));
|
pixels.set(m, n, 1, oldPixels.get(m, n, 1))
|
||||||
pixels.set(m, n, 2, oldPixels.get(m, n, 2));
|
pixels.set(m, n, 2, oldPixels.get(m, n, 2))
|
||||||
pixels.set(m, n, 3, oldPixels.get(m, n, 3));
|
pixels.set(m, n, 3, oldPixels.get(m, n, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
|
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "add-qr",
|
"name": "Add QR",
|
||||||
"description": "Adds QR corresponding to the given string",
|
"description": "Adds QR corresponding to the given string",
|
||||||
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
|
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ module.exports = function Average(options, UI) {
|
|||||||
sum[2] = Math.floor(sum[2] / divisor);
|
sum[2] = Math.floor(sum[2] / divisor);
|
||||||
sum[3] = Math.floor(sum[3] / divisor);
|
sum[3] = Math.floor(sum[3] / divisor);
|
||||||
|
|
||||||
i = 0;
|
i = 0
|
||||||
while (i < pixels.data.length) {
|
while (i < pixels.data.length) {
|
||||||
pixels.data[i++] = sum[0];
|
pixels.data[i++] = sum[0];
|
||||||
pixels.data[i++] = sum[1];
|
pixels.data[i++] = sum[1];
|
||||||
@@ -43,7 +43,7 @@ module.exports = function Average(options, UI) {
|
|||||||
options.step.metadata.averages = sum;
|
options.step.metadata.averages = sum;
|
||||||
|
|
||||||
// TODO: refactor into a new "display()" method as per https://github.com/publiclab/image-sequencer/issues/242
|
// TODO: refactor into a new "display()" method as per https://github.com/publiclab/image-sequencer/issues/242
|
||||||
if (options.step.inBrowser && options.step.ui) $(options.step.ui).find('.details').append('<p><b>Averages</b> (r, g, b, a): ' + sum.join(', ') + '</p>');
|
if (options.step.inBrowser && options.step.ui) $(options.step.ui).find('.details').append("<p><b>Averages</b> (r, g, b, a): " + sum.join(', ') + "</p>");
|
||||||
return pixels;
|
return pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,12 +58,10 @@ module.exports = function Average(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -72,5 +70,5 @@ module.exports = function Average(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "average",
|
"name": "Average",
|
||||||
"description": "Average all pixel color",
|
"description": "Average all pixel color",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ module.exports = function Dynamic(options, UI, util) {
|
|||||||
var step = this;
|
var step = this;
|
||||||
|
|
||||||
// convert to runnable code:
|
// convert to runnable code:
|
||||||
if (typeof options.func === 'string') eval('options.func = ' + options.func);
|
if (typeof options.func === "string") eval('options.func = ' + options.func);
|
||||||
|
|
||||||
var getPixels = require('get-pixels');
|
var getPixels = require('get-pixels');
|
||||||
|
|
||||||
// convert offset as string to int
|
// convert offset as string to int
|
||||||
if (typeof options.offset === 'string') options.offset = parseInt(options.offset);
|
if (typeof options.offset === "string") options.offset = parseInt(options.offset);
|
||||||
|
|
||||||
// save first image's pixels
|
// save first image's pixels
|
||||||
var priorStep = this.getStep(options.offset);
|
var priorStep = this.getStep(options.offset);
|
||||||
@@ -44,7 +44,7 @@ module.exports = function Dynamic(options, UI, util) {
|
|||||||
p.get(x, y, 1),
|
p.get(x, y, 1),
|
||||||
p.get(x, y, 2),
|
p.get(x, y, 2),
|
||||||
p.get(x, y, 3)
|
p.get(x, y, 3)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype) {
|
function output(image, datauri, mimetype) {
|
||||||
@@ -57,13 +57,11 @@ module.exports = function Dynamic(options, UI, util) {
|
|||||||
// run PixelManipulatin on second image's pixels
|
// run PixelManipulatin on second image's pixels
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
changePixel: changePixel,
|
changePixel: changePixel,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -73,5 +71,5 @@ module.exports = function Dynamic(options, UI, util) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "blend",
|
"name": "Blend",
|
||||||
"description": "Blend two chosen image steps with the given function. Defaults to using the red channel from image 1 and the green and blue and alpha channels of image 2. Easier to use interfaces coming soon!",
|
"description": "Blend two chosen image steps with the given function. Defaults to using the red channel from image 1 and the green and blue and alpha channels of image 2. Easier to use interfaces coming soon!",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"offset": {
|
"offset": {
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
module.exports = function(pixels, options, priorStep){
|
|
||||||
|
|
||||||
var $ = require('jquery'); // to make Blob-analysis work for node.js
|
|
||||||
|
|
||||||
var img = $(priorStep.imgElement);
|
|
||||||
if(Object.keys(img).length === 0){
|
|
||||||
img = $(priorStep.options.step.imgElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
canvas.width = pixels.shape[0];
|
|
||||||
canvas.height = pixels.shape[1];
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
ctx.drawImage(img[0], 0, 0);
|
|
||||||
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
|
|
||||||
let src = cv.matFromImageData(imgData);
|
|
||||||
let dst = new cv.Mat();
|
|
||||||
let gray = new cv.Mat();
|
|
||||||
let opening = new cv.Mat();
|
|
||||||
let imageBg = new cv.Mat();
|
|
||||||
let imageFg = new cv.Mat();
|
|
||||||
let distTrans = new cv.Mat();
|
|
||||||
let unknown = new cv.Mat();
|
|
||||||
let markers = new cv.Mat();
|
|
||||||
|
|
||||||
// gray and threshold image
|
|
||||||
cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
|
|
||||||
cv.threshold(gray, gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU);
|
|
||||||
|
|
||||||
// get background
|
|
||||||
let M = cv.Mat.ones(3, 3, cv.CV_8U);
|
|
||||||
cv.erode(gray, gray, M);
|
|
||||||
cv.dilate(gray, opening, M);
|
|
||||||
cv.dilate(opening, imageBg, M, new cv.Point(-1, -1), 3);
|
|
||||||
|
|
||||||
// distance transform
|
|
||||||
cv.distanceTransform(opening, distTrans, cv.DIST_L2, 5);
|
|
||||||
cv.normalize(distTrans, distTrans, 1, 0, cv.NORM_INF);
|
|
||||||
|
|
||||||
// get foreground
|
|
||||||
cv.threshold(distTrans, imageFg, 0.7 * 1, 255, cv.THRESH_BINARY);
|
|
||||||
imageFg.convertTo(imageFg, cv.CV_8U, 1, 0);
|
|
||||||
cv.subtract(imageBg, imageFg, unknown);
|
|
||||||
|
|
||||||
// get connected components markers
|
|
||||||
cv.connectedComponents(imageFg, markers);
|
|
||||||
for (let i = 0; i < markers.rows; i++) {
|
|
||||||
for (let j = 0; j < markers.cols; j++) {
|
|
||||||
markers.intPtr(i, j)[0] = markers.ucharPtr(i, j)[0] + 1;
|
|
||||||
if (unknown.ucharPtr(i, j)[0] == 255) {
|
|
||||||
markers.intPtr(i, j)[0] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cv.cvtColor(src, src, cv.COLOR_RGBA2RGB, 0);
|
|
||||||
cv.watershed(src, markers);
|
|
||||||
|
|
||||||
// draw barriers
|
|
||||||
for (let i = 0; i < markers.rows; i++) {
|
|
||||||
for (let j = 0; j < markers.cols; j++) {
|
|
||||||
if (markers.intPtr(i, j)[0] == -1) {
|
|
||||||
src.ucharPtr(i, j)[0] = 255; // R
|
|
||||||
src.ucharPtr(i, j)[1] = 0; // G
|
|
||||||
src.ucharPtr(i, j)[2] = 0; // B
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cv.imshow(canvas, src);
|
|
||||||
|
|
||||||
src.delete(); dst.delete(); gray.delete(); opening.delete(); imageBg.delete();
|
|
||||||
imageFg.delete(); distTrans.delete(); unknown.delete(); markers.delete(); M.delete();
|
|
||||||
|
|
||||||
var myImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
||||||
pixels.data = myImageData.data;
|
|
||||||
|
|
||||||
return pixels;
|
|
||||||
};
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
|
|
||||||
module.exports = function BlobAnalysis(options, UI){
|
|
||||||
|
|
||||||
var output;
|
|
||||||
|
|
||||||
function draw(input, callback, progressObj) {
|
|
||||||
|
|
||||||
progressObj.stop(true);
|
|
||||||
progressObj.overrideFlag = true;
|
|
||||||
|
|
||||||
var step = this;
|
|
||||||
|
|
||||||
var priorStep = this.getStep(-1); // get the previous step to process it
|
|
||||||
|
|
||||||
function extraManipulation(pixels){
|
|
||||||
|
|
||||||
pixels = require('./BlobAnalysis')(pixels, options, priorStep);
|
|
||||||
return pixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
function output(image, datauri, mimetype){
|
|
||||||
|
|
||||||
step.output = { src: datauri, format: mimetype};
|
|
||||||
}
|
|
||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
|
||||||
output: output,
|
|
||||||
extraManipulation: extraManipulation,
|
|
||||||
format: input.format,
|
|
||||||
image: options.image,
|
|
||||||
inBrowser: options.inBrowser,
|
|
||||||
callback: callback
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
options: options,
|
|
||||||
draw: draw,
|
|
||||||
output: output,
|
|
||||||
UI: UI
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
module.exports = [
|
|
||||||
require('./Module'),
|
|
||||||
require('./info.json')
|
|
||||||
];
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Blob Analysis",
|
|
||||||
"description": "Blob/Region identification for microscopic images.",
|
|
||||||
"inputs": {},
|
|
||||||
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blob-analysis"
|
|
||||||
}
|
|
||||||
@@ -1,62 +1,84 @@
|
|||||||
module.exports = exports = function(pixels, blur) {
|
module.exports = exports = function(pixels, blur) {
|
||||||
let kernel = kernelGenerator(blur),
|
let kernel = kernelGenerator(blur, 1), oldpix = require('lodash').cloneDeep(pixels);
|
||||||
pixs = {
|
kernel = flipKernel(kernel);
|
||||||
r: [],
|
|
||||||
g: [],
|
|
||||||
b: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let y = 0; y < pixels.shape[1]; y++){
|
for (let i = 0; i < pixels.shape[0]; i++) {
|
||||||
pixs.r.push([]);
|
for (let j = 0; j < pixels.shape[1]; j++) {
|
||||||
pixs.g.push([]);
|
let neighboutPos = getNeighbouringPixelPositions([i, j]);
|
||||||
pixs.b.push([]);
|
let acc = [0.0, 0.0, 0.0, 0.0];
|
||||||
|
for (let a = 0; a < kernel.length; a++) {
|
||||||
for (let x = 0; x < pixels.shape[0]; x++){
|
for (let b = 0; b < kernel.length; b++) {
|
||||||
pixs.r[y].push(pixels.get(x, y, 0));
|
acc[0] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 0) * kernel[a][b]);
|
||||||
pixs.g[y].push(pixels.get(x, y, 1));
|
acc[1] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 1) * kernel[a][b]);
|
||||||
pixs.b[y].push(pixels.get(x, y, 2));
|
acc[2] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 2) * kernel[a][b]);
|
||||||
|
acc[3] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 3) * kernel[a][b]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pixels.set(i, j, 0, acc[0]);
|
||||||
const convolve = require('../_nomodule/gpuUtils').convolve;
|
pixels.set(i, j, 1, acc[1]);
|
||||||
|
pixels.set(i, j, 2, acc[2]);
|
||||||
const conPix = convolve([pixs.r, pixs.g, pixs.b], kernel);
|
|
||||||
|
|
||||||
for (let y = 0; y < pixels.shape[1]; y++){
|
|
||||||
for (let x = 0; x < pixels.shape[0]; x++){
|
|
||||||
pixels.set(x, y, 0, Math.max(0, Math.min(conPix[0][y][x], 255)));
|
|
||||||
pixels.set(x, y, 1, Math.max(0, Math.min(conPix[1][y][x], 255)));
|
|
||||||
pixels.set(x, y, 2, Math.max(0, Math.min(conPix[2][y][x], 255)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pixels;
|
return pixels;
|
||||||
|
|
||||||
//Generates a 5x5 Gaussian kernel
|
|
||||||
function kernelGenerator(sigma = 1) {
|
|
||||||
|
|
||||||
let kernel = [],
|
|
||||||
sum = 0;
|
|
||||||
|
|
||||||
if (sigma == 0) sigma += 0.05;
|
//Generates a 3x3 Gaussian kernel
|
||||||
|
function kernelGenerator(sigma, size) {
|
||||||
|
|
||||||
const s = 2 * Math.pow(sigma, 2);
|
/*
|
||||||
|
Trying out a variable radius kernel not working as of now
|
||||||
|
*/
|
||||||
|
// const coeff = (1.0/(2.0*Math.PI*sigma*sigma))
|
||||||
|
// const expCoeff = -1 * (1.0/2.0 * sigma * sigma)
|
||||||
|
// let e = Math.E
|
||||||
|
// let result = []
|
||||||
|
// for(let i = -1 * size;i<=size;i++){
|
||||||
|
// let arr = []
|
||||||
|
// for(let j= -1 * size;j<=size;j++){
|
||||||
|
// arr.push(coeff * Math.pow(e,expCoeff * ((i * i) + (j*j))))
|
||||||
|
// }
|
||||||
|
// result.push(arr)
|
||||||
|
// }
|
||||||
|
// let sum = result.reduce((sum,val)=>{
|
||||||
|
// return val.reduce((sumInner,valInner)=>{
|
||||||
|
// return sumInner+valInner
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// result = result.map(arr=>arr.map(val=>(val + 0.0)/(sum + 0.0)))
|
||||||
|
|
||||||
for (let y = -2; y <= 2; y++) {
|
// return result
|
||||||
kernel.push([]);
|
|
||||||
for (let x = -2; x <= 2; x++) {
|
return [
|
||||||
let r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
|
[2.0 / 159.0, 4.0 / 159.0, 5.0 / 159.0, 4.0 / 159.0, 2.0 / 159.0],
|
||||||
kernel[y + 2].push(Math.exp(-(r / s)));
|
[4.0 / 159.0, 9.0 / 159.0, 12.0 / 159.0, 9.0 / 159.0, 4.0 / 159.0],
|
||||||
sum += kernel[y + 2][x + 2];
|
[5.0 / 159.0, 12.0 / 159.0, 15.0 / 159.0, 12.0 / 159.0, 5.0 / 159.0],
|
||||||
|
[4.0 / 159.0, 9.0 / 159.0, 12.0 / 159.0, 9.0 / 159.0, 4.0 / 159.0],
|
||||||
|
[2.0 / 159.0, 4.0 / 159.0, 5.0 / 159.0, 4.0 / 159.0, 2.0 / 159.0]
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
function getNeighbouringPixelPositions(pixelPosition) {
|
||||||
|
let x = pixelPosition[0], y = pixelPosition[1], result = [];
|
||||||
|
|
||||||
|
for (let i = -2; i <= 2; i++) {
|
||||||
|
let arr = [];
|
||||||
|
for (let j = -2; j <= 2; j++)
|
||||||
|
arr.push([x + i, y + j]);
|
||||||
|
|
||||||
|
result.push(arr);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let x = 0; x < 5; x++){
|
function flipKernel(kernel) {
|
||||||
for (let y = 0; y < 5; y++){
|
let result = [];
|
||||||
kernel[y][x] = (kernel[y][x] / sum);
|
for (let i = kernel.length - 1; i >= 0; i--) {
|
||||||
|
let arr = [];
|
||||||
|
for (let j = kernel[i].length - 1; j >= 0; j--) {
|
||||||
|
arr.push(kernel[i][j]);
|
||||||
|
}
|
||||||
|
result.push(arr);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return kernel;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ module.exports = function Blur(options, UI) {
|
|||||||
|
|
||||||
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
||||||
options.blur = options.blur || defaults.blur;
|
options.blur = options.blur || defaults.blur;
|
||||||
options.blur = parseFloat(options.blur);
|
|
||||||
var output;
|
var output;
|
||||||
|
|
||||||
function draw(input, callback, progressObj) {
|
function draw(input, callback, progressObj) {
|
||||||
@@ -29,12 +28,10 @@ module.exports = function Blur(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -43,5 +40,5 @@ module.exports = function Blur(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "blur",
|
"name": "Blur",
|
||||||
"description": "Applies a Gaussian blur given by the intensity value",
|
"description": "Applies a Gaussian blur given by the intensity value",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"blur": {
|
"blur": {
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"default": 2,
|
"default": 2,
|
||||||
"min": 0,
|
"min": 0,
|
||||||
"max": 5,
|
"max": 5,
|
||||||
"step": 0.05
|
"step": 0.25
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blur-module"
|
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blur-module"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ module.exports = function Brightness(options, UI) {
|
|||||||
For eg. progressObj = new SomeProgressModule()
|
For eg. progressObj = new SomeProgressModule()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var step = this, val = (options.brightness) / 100.0;
|
var step = this, val = (options.brightness) / 100.0;;
|
||||||
|
|
||||||
function changePixel(r, g, b, a) {
|
function changePixel(r, g, b, a) {
|
||||||
|
|
||||||
@@ -40,13 +40,11 @@ module.exports = function Brightness(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui, //don't pass this in if you don't want your module to support progress bars
|
|
||||||
changePixel: changePixel,
|
changePixel: changePixel,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -55,5 +53,5 @@ module.exports = function Brightness(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "brightness",
|
"name": "Brightness",
|
||||||
"description": "Change the brightness of the image by given percent value",
|
"description": "Change the brightness of the image by given percent value",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"brightness": {
|
"brightness": {
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ module.exports = function canvasResize(options, UI) {
|
|||||||
|
|
||||||
function draw(input, callback, progressObj) {
|
function draw(input, callback, progressObj) {
|
||||||
|
|
||||||
options.width = parseInt(options.width || defaults.width);
|
options.width = options.width || defaults.width;
|
||||||
options.height = parseInt(options.height || defaults.height);
|
options.height = options.height || defaults.height;
|
||||||
options.x = parseInt(options.x || defaults.x);
|
options.x = options.x || defaults.x;
|
||||||
options.y = parseInt(options.y || defaults.y);
|
options.y = options.y || defaults.y;
|
||||||
|
|
||||||
progressObj.stop(true);
|
progressObj.stop(true);
|
||||||
progressObj.overrideFlag = true;
|
progressObj.overrideFlag = true;
|
||||||
@@ -21,7 +21,8 @@ module.exports = function canvasResize(options, UI) {
|
|||||||
var step = this;
|
var step = this;
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
let newPixels = require('ndarray')(new Uint8Array(4 * options.width * options.height).fill(0), [options.width, options.height, 4]);
|
|
||||||
|
let newPixels = require('ndarray')(new Uint8Array(4 * options.width * options.height).fill(255), [options.width, options.height, 4]);
|
||||||
let iMax = options.width - options.x,
|
let iMax = options.width - options.x,
|
||||||
jMax = options.height - options.y;
|
jMax = options.height - options.y;
|
||||||
for (let i = 0; i < iMax && i < pixels.shape[0]; i++) {
|
for (let i = 0; i < iMax && i < pixels.shape[0]; i++) {
|
||||||
@@ -45,13 +46,11 @@ module.exports = function canvasResize(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -60,5 +59,5 @@ module.exports = function canvasResize(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "canvas-resize",
|
"name": "Resize Canvas",
|
||||||
"description": "This module resizes the canvas and overlays the ouput of the previous step at given location",
|
"description": "This module resizes the canvas and overlays the ouput of the previous step at given location",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"width": {
|
"width": {
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ module.exports = function Channel(options, UI) {
|
|||||||
var step = this;
|
var step = this;
|
||||||
|
|
||||||
function changePixel(r, g, b, a) {
|
function changePixel(r, g, b, a) {
|
||||||
if (options.channel === 'red') return [r, 0, 0, a];
|
if (options.channel === "red") return [r, 0, 0, a];
|
||||||
if (options.channel === 'green') return [0, g, 0, a];
|
if (options.channel === "green") return [0, g, 0, a];
|
||||||
if (options.channel === 'blue') return [0, 0, b, a];
|
if (options.channel === "blue") return [0, 0, b, a];
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype) {
|
function output(image, datauri, mimetype) {
|
||||||
@@ -31,13 +31,11 @@ module.exports = function Channel(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
changePixel: changePixel,
|
changePixel: changePixel,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -48,5 +46,5 @@ module.exports = function Channel(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "channel",
|
"name": "Channel",
|
||||||
"description": "Displays only one color channel of an image -- default is green",
|
"description": "Displays only one color channel of an image -- default is green",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"channel": {
|
"channel": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module.exports = function ColorTemperature(options, UI) {
|
|||||||
|
|
||||||
function draw(input, callback, progressObj) {
|
function draw(input, callback, progressObj) {
|
||||||
|
|
||||||
options.temperature = (options.temperature > '40000') ? '40000' : options.temperature;
|
options.temperature = (options.temperature > "40000") ? "40000" : options.temperature
|
||||||
|
|
||||||
progressObj.stop(true);
|
progressObj.stop(true);
|
||||||
progressObj.overrideFlag = true;
|
progressObj.overrideFlag = true;
|
||||||
@@ -13,8 +13,8 @@ module.exports = function ColorTemperature(options, UI) {
|
|||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
|
|
||||||
let temp = parseInt(options.temperature);
|
let temp = parseInt(options.temperature)
|
||||||
temp /= 100;
|
temp /= 100
|
||||||
|
|
||||||
let r, g, b;
|
let r, g, b;
|
||||||
|
|
||||||
@@ -38,21 +38,21 @@ module.exports = function ColorTemperature(options, UI) {
|
|||||||
for (let i = 0; i < pixels.shape[0]; i++) {
|
for (let i = 0; i < pixels.shape[0]; i++) {
|
||||||
for (let j = 0; j < pixels.shape[1]; j++) {
|
for (let j = 0; j < pixels.shape[1]; j++) {
|
||||||
|
|
||||||
r_data = pixels.get(i, j, 0);
|
r_data = pixels.get(i, j, 0)
|
||||||
r_new_data = (255 / r) * r_data;
|
r_new_data = (255 / r) * r_data
|
||||||
pixels.set(i, j, 0, r_new_data);
|
pixels.set(i, j, 0, r_new_data)
|
||||||
|
|
||||||
g_data = pixels.get(i, j, 1);
|
g_data = pixels.get(i, j, 1)
|
||||||
g_new_data = (255 / g) * g_data;
|
g_new_data = (255 / g) * g_data
|
||||||
pixels.set(i, j, 1, g_new_data);
|
pixels.set(i, j, 1, g_new_data)
|
||||||
|
|
||||||
b_data = pixels.get(i, j, 2);
|
b_data = pixels.get(i, j, 2)
|
||||||
b_new_data = (255 / b) * b_data;
|
b_new_data = (255 / b) * b_data
|
||||||
pixels.set(i, j, 2, b_new_data);
|
pixels.set(i, j, 2, b_new_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pixels;
|
return pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype) {
|
function output(image, datauri, mimetype) {
|
||||||
@@ -63,13 +63,11 @@ module.exports = function ColorTemperature(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +76,6 @@ module.exports = function ColorTemperature(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
|
|
||||||
};
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "color-temperature",
|
"name": "Color Temperature",
|
||||||
"description": "Changes the color temperature of the image.",
|
"description": "Changes the color temperature of the image.",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"temperature": {
|
"temperature": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "colorbar",
|
"name": "Colorbar",
|
||||||
"description": "Generates a colorbar to lay over the image",
|
"description": "Generates a colorbar to lay over the image",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"colormap": {
|
"colormap": {
|
||||||
|
|||||||
@@ -14,14 +14,14 @@
|
|||||||
module.exports = function Colormap(value, options) {
|
module.exports = function Colormap(value, options) {
|
||||||
options.colormap = options.colormap || colormaps.default;
|
options.colormap = options.colormap || colormaps.default;
|
||||||
// if a lookup table is provided as an array:
|
// if a lookup table is provided as an array:
|
||||||
if(typeof(options.colormap) == 'object')
|
if(typeof(options.colormap) == "object")
|
||||||
colormapFunction = colormap(options.colormap);
|
colormapFunction = colormap(options.colormap);
|
||||||
// if a stored colormap is named with a string like "fastie":
|
// if a stored colormap is named with a string like "fastie":
|
||||||
else if(colormaps.hasOwnProperty(options.colormap))
|
else if(colormaps.hasOwnProperty(options.colormap))
|
||||||
colormapFunction = colormaps[options.colormap];
|
colormapFunction = colormaps[options.colormap];
|
||||||
else colormapFunction = colormaps.default;
|
else colormapFunction = colormaps.default;
|
||||||
return colormapFunction(value / 255.00);
|
return colormapFunction(value / 255.00);
|
||||||
};
|
}
|
||||||
|
|
||||||
function colormap(segments) {
|
function colormap(segments) {
|
||||||
return function(x) {
|
return function(x) {
|
||||||
@@ -49,7 +49,7 @@ function colormap(segments) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
var colormaps = {
|
var colormaps = {
|
||||||
greyscale: colormap([
|
greyscale: colormap([
|
||||||
@@ -194,4 +194,4 @@ var colormaps = {
|
|||||||
[0.9, [255, 50, 50], [255, 50, 50] ]
|
[0.9, [255, 50, 50], [255, 50, 50] ]
|
||||||
])
|
])
|
||||||
|
|
||||||
};
|
}
|
||||||
@@ -24,13 +24,11 @@ module.exports = function Colormap(options, UI) {
|
|||||||
}
|
}
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
changePixel: changePixel,
|
changePixel: changePixel,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
inBrowser: options.inBrowser,
|
inBrowser: options.inBrowser,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -40,5 +38,5 @@ module.exports = function Colormap(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "colormap",
|
"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.",
|
"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": {
|
"inputs": {
|
||||||
"colormap": {
|
"colormap": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ var _ = require('lodash');
|
|||||||
|
|
||||||
module.exports = exports = function(pixels, contrast) {
|
module.exports = exports = function(pixels, contrast) {
|
||||||
let oldpix = _.cloneDeep(pixels);
|
let oldpix = _.cloneDeep(pixels);
|
||||||
contrast = Number(contrast);
|
contrast = Number(contrast)
|
||||||
if (contrast < -100) contrast = -100;
|
if (contrast < -100) contrast = -100;
|
||||||
if (contrast > 100) contrast = 100;
|
if (contrast > 100) contrast = 100;
|
||||||
contrast = (100.0 + contrast) / 100.0;
|
contrast = (100.0 + contrast) / 100.0;
|
||||||
@@ -44,4 +44,4 @@ module.exports = exports = function(pixels, contrast) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pixels;
|
return pixels;
|
||||||
};
|
}
|
||||||
@@ -16,8 +16,8 @@ module.exports = function Contrast(options, UI) {
|
|||||||
var step = this;
|
var step = this;
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
pixels = require('./Contrast')(pixels, options.contrast);
|
pixels = require('./Contrast')(pixels, options.contrast)
|
||||||
return pixels;
|
return pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype) {
|
function output(image, datauri, mimetype) {
|
||||||
@@ -29,12 +29,10 @@ module.exports = function Contrast(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -43,5 +41,5 @@ module.exports = function Contrast(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "contrast",
|
"name": "Contrast",
|
||||||
"description": "Change the contrast of the image by given value",
|
"description": "Change the contrast of the image by given value",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"contrast": {
|
"contrast": {
|
||||||
|
|||||||
@@ -1,50 +1,71 @@
|
|||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
module.exports = exports = function(pixels, constantFactor, kernelValues, texMode) {
|
module.exports = exports = function(pixels, constantFactor, kernelValues) {
|
||||||
let kernel = kernelGenerator(constantFactor, kernelValues),
|
let kernel = kernelGenerator(constantFactor, kernelValues), oldpix = _.cloneDeep(pixels);
|
||||||
pixs = {
|
kernel = flipKernel(kernel);
|
||||||
r: [],
|
|
||||||
g: [],
|
|
||||||
b: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let y = 0; y < pixels.shape[1]; y++){
|
for (let i = 0; i < pixels.shape[0]; i++) {
|
||||||
pixs.r.push([]);
|
for (let j = 0; j < pixels.shape[1]; j++) {
|
||||||
pixs.g.push([]);
|
let neighboutPos = getNeighbouringPixelPositions([i, j]);
|
||||||
pixs.b.push([]);
|
let acc = [0.0, 0.0, 0.0, 0.0];
|
||||||
|
for (let a = 0; a < kernel.length; a++) {
|
||||||
for (let x = 0; x < pixels.shape[0]; x++){
|
for (let b = 0; b < kernel.length; b++) {
|
||||||
pixs.r[y].push(pixels.get(x, y, 0));
|
acc[0] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 0) * kernel[a][b]);
|
||||||
pixs.g[y].push(pixels.get(x, y, 1));
|
acc[1] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 1) * kernel[a][b]);
|
||||||
pixs.b[y].push(pixels.get(x, y, 2));
|
acc[2] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 2) * kernel[a][b]);
|
||||||
|
acc[3] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 3) * kernel[a][b]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
acc[0] = Math.min(acc[0], 255);
|
||||||
const convolve = require('../_nomodule/gpuUtils').convolve;
|
acc[1] = Math.min(acc[1], 255);
|
||||||
const conPix = convolve([pixs.r, pixs.g, pixs.b], kernel, (pixels.shape[0] * pixels.shape[1]) < 400000 ? true : false);
|
acc[2] = Math.min(acc[2], 255);
|
||||||
|
pixels.set(i, j, 0, acc[0]);
|
||||||
for (let y = 0; y < pixels.shape[1]; y++){
|
pixels.set(i, j, 1, acc[1]);
|
||||||
for (let x = 0; x < pixels.shape[0]; x++){
|
pixels.set(i, j, 2, acc[2]);
|
||||||
pixels.set(x, y, 0, Math.max(0, Math.min(conPix[0][y][x], 255)));
|
|
||||||
pixels.set(x, y, 1, Math.max(0, Math.min(conPix[1][y][x], 255)));
|
|
||||||
pixels.set(x, y, 2, Math.max(0, Math.min(conPix[2][y][x], 255)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pixels;
|
return pixels;
|
||||||
};
|
|
||||||
|
|
||||||
function kernelGenerator(constantFactor, kernelValues) {
|
function kernelGenerator(constantFactor, kernelValues) {
|
||||||
kernelValues = kernelValues.split(' ');
|
kernelValues = kernelValues.split(" ");
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 9; i++) {
|
||||||
kernelValues[i] = Number(kernelValues[i]) * constantFactor;
|
kernelValues[i] = Number(kernelValues[i]) * constantFactor;
|
||||||
}
|
}
|
||||||
let k = 0;
|
let k = 0;
|
||||||
let arr = [];
|
let arr = [];
|
||||||
for (y = 0; y < 3; y++) {
|
for (i = 0; i < 3; i++) {
|
||||||
arr.push([]);
|
let columns = [];
|
||||||
for (x = 0; x < 3; x++) {
|
for (j = 0; j < 3; j++) {
|
||||||
arr[y].push(kernelValues[k]);
|
columns.push(kernelValues[k]);
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
|
arr.push(columns);
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNeighbouringPixelPositions(pixelPosition) {
|
||||||
|
let x = pixelPosition[0], y = pixelPosition[1], result = [];
|
||||||
|
|
||||||
|
for (let i = -1; i <= 1; i++) {
|
||||||
|
let arr = [];
|
||||||
|
for (let j = -1; j <= 1; j++)
|
||||||
|
arr.push([x + i, y + j]);
|
||||||
|
|
||||||
|
result.push(arr);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function flipKernel(kernel) {
|
||||||
|
let result = [];
|
||||||
|
for (let i = kernel.length - 1; i >= 0; i--) {
|
||||||
|
let arr = [];
|
||||||
|
for (let j = kernel[i].length - 1; j >= 0; j--) {
|
||||||
|
arr.push(kernel[i][j]);
|
||||||
|
}
|
||||||
|
result.push(arr);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ module.exports = function Convolution(options, UI) {
|
|||||||
|
|
||||||
options.kernelValues = options.kernelValues || defaults.kernelValues;
|
options.kernelValues = options.kernelValues || defaults.kernelValues;
|
||||||
options.constantFactor = options.constantFactor || defaults.constantFactor;
|
options.constantFactor = options.constantFactor || defaults.constantFactor;
|
||||||
options.texMode = options.texMode || defaults.texMode;
|
|
||||||
var output;
|
var output;
|
||||||
|
|
||||||
function draw(input, callback, progressObj) {
|
function draw(input, callback, progressObj) {
|
||||||
@@ -15,7 +14,7 @@ module.exports = function Convolution(options, UI) {
|
|||||||
var step = this;
|
var step = this;
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
pixels = require('./Convolution')(pixels, options.constantFactor, options.kernelValues, options.texMode);
|
pixels = require('./Convolution')(pixels, options.constantFactor, options.kernelValues);
|
||||||
return pixels;
|
return pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,12 +26,10 @@ module.exports = function Convolution(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -41,5 +38,5 @@ module.exports = function Convolution(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "convolution",
|
"name": "Convolution",
|
||||||
"description": "Image Convolution using a given 3x3 kernel matrix <a href='https://en.wikipedia.org/wiki/Kernel_(image_processing)'>Read more</a>",
|
"description": "Image Convolution using a given 3x3 kernel matrix <a href='https://en.wikipedia.org/wiki/Kernel_(image_processing)'>Read more</a>",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"constantFactor":{
|
"constantFactor":{
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"desc": "a constant factor, multiplies all the kernel values by that factor",
|
"desc": "a constant factor, multiplies all the kernel values by that factor",
|
||||||
"default": 0.111,
|
"default": 0.1111,
|
||||||
"min": 0.001,
|
"placeholder": 0.1111
|
||||||
"max": 2,
|
|
||||||
"step": 0.001
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"kernelValues": {
|
"kernelValues": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"desc": "nine space separated numbers representing the kernel values in left to right and top to bottom format.",
|
"desc": "nine space separated numbers representing the kernel values in left to right and top to bottom format.",
|
||||||
|
|||||||
@@ -17,26 +17,18 @@ module.exports = function Crop(input, options, callback) {
|
|||||||
var iw = pixels.shape[0]; //Width of Original Image
|
var iw = pixels.shape[0]; //Width of Original Image
|
||||||
var ih = pixels.shape[1]; //Height of Original Image
|
var ih = pixels.shape[1]; //Height of Original Image
|
||||||
var backgroundArray = [];
|
var backgroundArray = [];
|
||||||
backgroundColor = options.backgroundColor.substring(options.backgroundColor.indexOf('(') + 1, options.backgroundColor.length - 1); // extract only the values from rgba(_,_,_,_)
|
backgroundColor = options.backgroundColor.split(" ");
|
||||||
backgroundColor = backgroundColor.split(',');
|
|
||||||
for(var i = 0; i < w ; i++){
|
for(var i = 0; i < w ; i++){
|
||||||
backgroundArray = backgroundArray.concat([backgroundColor[0],backgroundColor[1],backgroundColor[2],backgroundColor[3]]);
|
backgroundArray = backgroundArray.concat([backgroundColor[0],backgroundColor[1],backgroundColor[2],backgroundColor[3]]);
|
||||||
}
|
}
|
||||||
// var newarray = new Uint8Array(4*w*h);
|
var newarray = new Uint8Array(4*w*h);
|
||||||
var array = [];
|
|
||||||
for (var n = oy; n < oy + h; n++) {
|
for (var n = oy; n < oy + h; n++) {
|
||||||
var offsetValue = 4 * w * n;
|
|
||||||
if(n<ih){
|
if(n<ih){
|
||||||
var start = n * 4 * iw + ox * 4;
|
newarray.set(pixels.data.slice(n*4*iw + ox, n*4*iw + ox + 4*w),4*w*(n-oy));
|
||||||
var end = n * 4 * iw + ox * 4 + 4 * w;
|
|
||||||
var pushArray = Array.from(pixels.data.slice(start, end ));
|
|
||||||
array.push.apply(array, pushArray);
|
|
||||||
} else {
|
} else {
|
||||||
array.push.apply(array, backgroundArray);
|
newarray.set(backgroundArray,4*w*(n-oy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newarray = Uint8Array.from(array);
|
|
||||||
pixels.data = newarray;
|
pixels.data = newarray;
|
||||||
pixels.shape = [w,h,4];
|
pixels.shape = [w,h,4];
|
||||||
pixels.stride[1] = 4*w;
|
pixels.stride[1] = 4*w;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ module.exports = function CropModule(options, UI) {
|
|||||||
step.output = {
|
step.output = {
|
||||||
src: out,
|
src: out,
|
||||||
format: format
|
format: format
|
||||||
};
|
}
|
||||||
|
|
||||||
// This output is accessible to the UI
|
// This output is accessible to the UI
|
||||||
options.step.output = out;
|
options.step.output = out;
|
||||||
@@ -81,5 +81,5 @@ module.exports = function CropModule(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ module.exports = function CropModuleUi(step, ui) {
|
|||||||
converted[2],
|
converted[2],
|
||||||
converted[3]
|
converted[3]
|
||||||
);
|
);
|
||||||
$($(imgEl()).parents()[3]).find('input').trigger('change');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -56,7 +55,7 @@ module.exports = function CropModuleUi(step, ui) {
|
|||||||
Math.floor(( _y / displayHeight ) * inputHeight),
|
Math.floor(( _y / displayHeight ) * inputHeight),
|
||||||
Math.floor(( _width / displayWidth ) * inputWidth),
|
Math.floor(( _width / displayWidth ) * inputWidth),
|
||||||
Math.floor(( _height / displayHeight ) * inputHeight)
|
Math.floor(( _height / displayHeight ) * inputHeight)
|
||||||
];
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove() {
|
function remove() {
|
||||||
@@ -78,7 +77,7 @@ module.exports = function CropModuleUi(step, ui) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setOptions(x1, y1, width, height) {
|
function setOptions(x1, y1, width, height) {
|
||||||
let options = $($(imgEl()).parents()[3]).find('input');
|
let options = $($(imgEl()).parents()[2]).find("input");
|
||||||
options[0].value = x1;
|
options[0].value = x1;
|
||||||
options[1].value = y1;
|
options[1].value = y1;
|
||||||
options[2].value = width;
|
options[2].value = width;
|
||||||
@@ -94,5 +93,5 @@ module.exports = function CropModuleUi(step, ui) {
|
|||||||
setup: setup,
|
setup: setup,
|
||||||
remove: remove,
|
remove: remove,
|
||||||
hide: hide
|
hide: hide
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,33 +1,33 @@
|
|||||||
{
|
{
|
||||||
"name": "crop",
|
"name": "Crop",
|
||||||
"description": "Crop image to given x, y, w, h in pixels or % , measured from top left",
|
"description": "Crop image to given x, y, w, h in pixels or % , measured from top left",
|
||||||
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
|
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"x": {
|
"x": {
|
||||||
"type": "string",
|
"type": "integer",
|
||||||
"desc": "X-position (measured from left) from where cropping starts",
|
"desc": "X-position (measured from left) from where cropping starts",
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"y": {
|
"y": {
|
||||||
"type": "string",
|
"type": "integer",
|
||||||
"desc": "Y-position (measured from top) from where cropping starts",
|
"desc": "Y-position (measured from top) from where cropping starts",
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"w": {
|
"w": {
|
||||||
"type": "string",
|
"type": "integer",
|
||||||
"desc": "Width of crop",
|
"desc": "Width of crop",
|
||||||
"default": "(50%)"
|
"default": "(50%)"
|
||||||
},
|
},
|
||||||
"h": {
|
"h": {
|
||||||
"type": "string",
|
"type": "integer",
|
||||||
"desc": "Height of crop",
|
"desc": "Height of crop",
|
||||||
"default": "(50%)"
|
"default": "(50%)"
|
||||||
},
|
},
|
||||||
"backgroundColor": {
|
"backgroundColor": {
|
||||||
"type": "text",
|
"type": "string",
|
||||||
"desc": "Background Color",
|
"desc": "Background Color (Four space separated RGBA values)",
|
||||||
"default": "rgba(255,255,255,255)",
|
"default": "255 255 255 255",
|
||||||
"id": "color-picker"
|
"placeholder": "255 255 255 255"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#crop-module"
|
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#crop-module"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ module.exports = function DoNothing(options, UI) {
|
|||||||
|
|
||||||
|
|
||||||
// Tell Image Sequencer that this step is complete
|
// Tell Image Sequencer that this step is complete
|
||||||
options.step.qrval = (decoded) ? decoded.data : 'undefined';
|
options.step.qrval = (decoded)?decoded.data:"undefined";
|
||||||
});
|
});
|
||||||
|
|
||||||
function output(image, datauri, mimetype){
|
function output(image, datauri, mimetype){
|
||||||
@@ -37,11 +37,9 @@ module.exports = function DoNothing(options, UI) {
|
|||||||
}
|
}
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -51,5 +49,5 @@ module.exports = function DoNothing(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "decode-qr",
|
"name": "Decode QR",
|
||||||
"description": "Search for and decode a QR code in the image",
|
"description": "Search for and decode a QR code in the image",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ module.exports = function Dither(pixels, type) {
|
|||||||
|
|
||||||
for (let currentPixel = 0; currentPixel <= imageDataLength; currentPixel += 4) {
|
for (let currentPixel = 0; currentPixel <= imageDataLength; currentPixel += 4) {
|
||||||
|
|
||||||
if (type === 'none') {
|
if (type === "none") {
|
||||||
// No dithering
|
// No dithering
|
||||||
pixels.data[currentPixel] = pixels.data[currentPixel] < threshold ? 0 : 255;
|
pixels.data[currentPixel] = pixels.data[currentPixel] < threshold ? 0 : 255;
|
||||||
|
|
||||||
} else if (type === 'bayer') {
|
} else if (type === "bayer") {
|
||||||
|
|
||||||
// 4x4 Bayer ordered dithering algorithm
|
// 4x4 Bayer ordered dithering algorithm
|
||||||
let x = currentPixel / 4 % w;
|
let x = currentPixel / 4 % w;
|
||||||
@@ -40,7 +40,7 @@ module.exports = function Dither(pixels, type) {
|
|||||||
let map = Math.floor((pixels.data[currentPixel] + bayerThresholdMap[x % 4][y % 4]) / 2);
|
let map = Math.floor((pixels.data[currentPixel] + bayerThresholdMap[x % 4][y % 4]) / 2);
|
||||||
pixels.data[currentPixel] = (map < threshold) ? 0 : 255;
|
pixels.data[currentPixel] = (map < threshold) ? 0 : 255;
|
||||||
|
|
||||||
} else if (type === 'floydsteinberg') {
|
} else if (type === "floydsteinberg") {
|
||||||
|
|
||||||
// Floyd–Steinberg dithering algorithm
|
// Floyd–Steinberg dithering algorithm
|
||||||
newPixel = pixels.data[currentPixel] < 129 ? 0 : 255;
|
newPixel = pixels.data[currentPixel] < 129 ? 0 : 255;
|
||||||
@@ -73,4 +73,4 @@ module.exports = function Dither(pixels, type) {
|
|||||||
}
|
}
|
||||||
return pixels;
|
return pixels;
|
||||||
|
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ module.exports = function Dither(options, UI) {
|
|||||||
options.dither = options.dither || defaults.dither;
|
options.dither = options.dither || defaults.dither;
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
pixels = require('./Dither')(pixels, options.dither);
|
pixels = require('./Dither')(pixels, options.dither)
|
||||||
return pixels;
|
return pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype){
|
function output(image, datauri, mimetype){
|
||||||
@@ -23,12 +23,10 @@ module.exports = function Dither(options, UI) {
|
|||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
return require('../_nomodule/PixelManipulation.js')(input, {
|
||||||
output: output,
|
output: output,
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
extraManipulation: extraManipulation,
|
||||||
format: input.format,
|
format: input.format,
|
||||||
image: options.image,
|
image: options.image,
|
||||||
callback: callback,
|
callback: callback
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -36,5 +34,5 @@ module.exports = function Dither(options, UI) {
|
|||||||
draw: draw,
|
draw: draw,
|
||||||
output: output,
|
output: output,
|
||||||
UI: UI
|
UI: UI
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
require('./Module'),
|
require('./Module'),
|
||||||
require('./info.json')
|
require('./info.json')
|
||||||
];
|
]
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user