Compare commits

..

2 Commits

Author SHA1 Message Date
Jeffrey Warren
e562cae6a0 Update .codecov.yml 2019-04-15 17:09:50 -05:00
Jeffrey Warren
40c91483ab Add codecov comments 2019-04-15 16:32:36 -05:00
265 changed files with 5480 additions and 9291 deletions

View File

@@ -1 +0,0 @@
dist/*

View File

@@ -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
}
};

View File

@@ -1,12 +1,13 @@
sudo: required
language: node_js
node_js:
- '6'
- '8'
- '10'
env:
- CXX=g++-4.8
before_script:
- 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
- chmod +x ./cc-test-reporter
- ./cc-test-reporter before-build
@@ -25,10 +26,6 @@ addons:
packages:
- g++-4.8
- 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:
- export DISPLAY=':99.0' # for tape-run
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & # for tape-run

View File

@@ -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`.
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.
## Jump To
@@ -16,7 +12,6 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
* [Info File](#info-file)
* [Ideas](#Contribution-ideas)
* [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.
### Module example
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
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.
@@ -403,56 +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.
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.
## 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;
#### 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();
```

View File

@@ -1,76 +1,76 @@
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-uglify-es');
grunt.loadNpmTasks('grunt-browser-sync');
grunt.loadNpmTasks("grunt-browserify");
grunt.loadNpmTasks("grunt-contrib-uglify-es");
grunt.loadNpmTasks("grunt-browser-sync");
require('matchdep')
.filterDev('grunt-*')
require("matchdep")
.filterDev("grunt-*")
.forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
pkg: grunt.file.readJSON("package.json"),
watch: {
options: {
livereload: true
},
source: {
files: ['src/**/*', 'Gruntfile.js', 'examples/lib/*', 'examples/demo.js'],
tasks: ['compile']
files: ["src/**/*", "Gruntfile.js", "examples/lib/*", "examples/demo.js"],
tasks: ["compile"]
}
},
browserify: {
core: {
src: ['src/ImageSequencer.js'],
dest: 'dist/image-sequencer.js'
src: ["src/ImageSequencer.js"],
dest: "dist/image-sequencer.js"
},
ui: {
src: ['examples/demo.js'],
dest: 'dist/image-sequencer-ui.js'
src: ["examples/demo.js"],
dest: "dist/image-sequencer-ui.js"
},
prodcore: {
src: ['src/ImageSequencer.js'],
dest: 'dist/image-sequencer.brow.js'
src: ["src/ImageSequencer.js"],
dest: "dist/image-sequencer.brow.js"
},
produi: {
src: ['examples/demo.js'],
dest: 'dist/image-sequencer-ui.brow.js'
src: ["examples/demo.js"],
dest: "dist/image-sequencer-ui.brow.js"
}
},
uglify: {
core: {
src: ['./dist/image-sequencer.js'],
dest: './dist/image-sequencer.min.js'
src: ["./dist/image-sequencer.js"],
dest: "./dist/image-sequencer.min.js"
},
ui: {
src: ['dist/image-sequencer-ui.js'],
dest: 'dist/image-sequencer-ui.min.js'
},
prodcore: {
src: ['dist/image-sequencer.brow.js'],
dest: 'dist/image-sequencer.js'
src: ["dist/image-sequencer.brow.js"],
dest: "dist/image-sequencer.js"
},
produi: {
src: ['dist/image-sequencer-ui.brow.js'],
dest: 'dist/image-sequencer-ui.js'
src: ["dist/image-sequencer-ui.brow.js"],
dest: "dist/image-sequencer-ui.js"
}
},
browserSync: {
dev: {
options: {
watchTask: true,
server: './'
server: "./"
}
}
}
});
/* Default (development): Watch files and build on change. */
grunt.registerTask('default', ['watch']);
grunt.registerTask('build', ['browserify:core', 'browserify:ui', 'uglify:core', 'uglify:ui']);
grunt.registerTask('serve', ['browserify:core', 'browserify:ui', 'browserSync', 'watch']);
grunt.registerTask('compile', ['browserify:core', 'browserify:ui']);
grunt.registerTask('production', ['browserify:prodcore', 'browserify:produi', 'uglify:prodcore', 'uglify:produi']);
grunt.registerTask("default", ["watch"]);
grunt.registerTask("build", ["browserify:core", "browserify:ui", "uglify:core", "uglify:ui"]);
grunt.registerTask("serve", ["browserify:core", "browserify:ui", "browserSync", "watch"]);
grunt.registerTask("compile", ["browserify:core", "browserify:ui"]);
grunt.registerTask("production", ["browserify:prodcore", "browserify:produi", "uglify:prodcore", "uglify:produi"]);
};

View File

@@ -2,7 +2,7 @@ Image Sequencer
====
[![Build Status](https://travis-ci.org/publiclab/image-sequencer.svg?branch=master)](https://travis-ci.org/publiclab/image-sequencer) [![Maintainability](https://api.codeclimate.com/v1/badges/5906996dd2e90aca6398/maintainability)](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) [![Codecov](https://img.shields.io/codecov/c/github/publiclab/image-sequencer.svg?logo=codecov)](https://codecov.io/gh/publiclab/image-sequencer)
[![Build Status](https://travis-ci.org/publiclab/image-sequencer.svg?branch=master)](https://travis-ci.org/publiclab/image-sequencer) [![Maintainability](https://api.codeclimate.com/v1/badges/5906996dd2e90aca6398/maintainability)](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) ![Codecov](https://img.shields.io/codecov/c/github/publiclab/image-sequencer.svg?logo=codecov)
- **Latest Stable Demo**: https://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).
### 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
Our npm scripts do not support windows shells, please run the following snippet in PowerShell.
@@ -95,7 +95,7 @@ $ npm install image-sequencer -g
```
$ npm run debug invert
```
## Quick Usage
### Initializing the Sequencer
@@ -115,7 +115,7 @@ Note: Browser CORS Restrictions apply. Some browsers may not allow local images
from other folders, and throw a Security Error instead.
```js
sequencer.replaceImage(selector,steps,optional_options);
sequencer.replaceImage(selector,steps,optional_options);
```
`optional_options` allows passing additional arguments to the module itself.
@@ -123,8 +123,8 @@ sequencer.replaceImage(selector,steps,optional_options);
For example:
```js
sequencer.replaceImage('#photo','invert');
sequencer.replaceImage('#photo',['invert','ndvi-red']);
sequencer.replaceImage('#photo','invert');
sequencer.replaceImage('#photo',['invert','ndvi-red']);
```
### Data URL usage
@@ -150,7 +150,7 @@ Image Sequencer also provides a CLI for applying operations to local files. The
The basic format for using the CLI is as follows:
```
$ ./index.js -i [PATH] -s step-name
$ ./index.js -i [PATH] -s step-name
```
*NOTE:* On Windows you'll have to use `node index.js` instead of `./index.js`.
@@ -158,7 +158,7 @@ $ ./index.js -i [PATH] -s step-name
The CLI also can take multiple steps at once, like so:
```
$ ./index.js -i [PATH] -s "step-name-1 step-name-2 ..."
$ ./index.js -i [PATH] -s "step-name-1 step-name-2 ..."
```
But for this, double quotes must wrap the space-separated steps.
@@ -201,17 +201,15 @@ var sequencer = ImageSequencer();
### Loading an Image into the Sequencer
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
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 browsers, it may be a DatURI, a local image or a URL (Unless this violates
CORS Restrictions). To sum up, these are accepted:
* Images in the same domain (or directory - for a local implementation)
* CORS-Proof images in another domain.
* DataURLs
@@ -221,7 +219,7 @@ The callback is called within the scope of a sequencer. For example:
(addSteps is defined later)
```js
sequencer.loadImage('SRC', function(){
sequencer.loadImage('SRC',function(){
this.addSteps('module-name');
});
```
@@ -243,39 +241,7 @@ If multiple images are to be added, `modules` is an array, which holds the names
to be added, in that particular order.
optional_otions is just an optional parameter, in object form, which you might
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}')
```
want to provide to the modules.
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{}
```
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()
```
@@ -471,7 +437,7 @@ sequencer.importJSON([
To see this in action, please refer to line # 51 of the following:
[test/core/modules/import-export.js](https://github.com/publiclab/image-sequencer/blob/main/test/core/modules/import-export.js)
## Creating a User Interface
@@ -548,7 +514,7 @@ sequencer.setUI({
Image Sequencer object supports one imageURL at a time.
Adding a seccond image to same sequencer will result to adding same set of steps added to prior image and flushing out the previous one.
Adding a seccond image to same sequencer will result to adding same set of steps added to prior image and flushing out the previous one.
```js
s1 = new ImageSequencer(...);
@@ -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.
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

Binary file not shown.

View File

@@ -271,8 +271,4 @@ a.name-header{
margin-bottom:0px;
align:center;
width:100%;
}
.toggle {
cursor: default;
}
}

View File

@@ -1,9 +1,9 @@
var defaultHtmlSequencerUi = require('./lib/defaultHtmlSequencerUi.js'),
setupCache = require('./lib/cache.js'),
intermediateHtmlStepUi = require('./lib/intermediateHtmlStepUi.js'),
DefaultHtmlStepUi = require('./lib/defaultHtmlStepUi.js'),
urlHash = require('./lib/urlHash.js'),
insertPreview = require('./lib/insertPreview.js');
setupCache = require('./lib/cache.js'),
intermediateHtmlStepUi = require('./lib/intermediateHtmlStepUi.js'),
DefaultHtmlStepUi = require('./lib/defaultHtmlStepUi.js'),
urlHash = require('./lib/urlHash.js'),
insertPreview = require('./lib/insertPreview.js');
window.onload = function() {
sequencer = ImageSequencer();
@@ -12,21 +12,21 @@ window.onload = function() {
// Load information of all modules (Name, Inputs, Outputs)
var modulesInfo = sequencer.modulesInfo();
var addStepSelect = $('#addStep select');
addStepSelect.html('');
var addStepSelect = $("#addStep select");
addStepSelect.html("");
// Add modules to the addStep dropdown
for (var m in modulesInfo) {
if (modulesInfo[m] && modulesInfo[m].name)
addStepSelect.append(
'<option value="' + m + '">' + modulesInfo[m].name + '</option>'
'<option value="' + m + '">' + modulesInfo[m].name + "</option>"
);
}
// Null option
addStepSelect.append('<option value="" disabled selected>Select a Module</option>');
addStepSelect.selectize({
sortField: 'text'
});
});
}
refreshOptions();
@@ -36,7 +36,7 @@ window.onload = function() {
var shouldDisplay = $('body').scrollTop() > 20 || $(':root').scrollTop() > 20;
$('#move-up').css({
display: shouldDisplay ? 'block' : 'none'
display: shouldDisplay ? 'block' : 'none'
});
}
@@ -46,7 +46,7 @@ window.onload = function() {
$(':root').animate({scrollTop: 0});
}
$('#move-up').on('click', topFunction);
$('#move-up').on("click",topFunction);
// UI for each step:
@@ -59,43 +59,48 @@ window.onload = function() {
if (urlHash.getUrlHashParameter('src')) {
sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad);
} else {
sequencer.loadImage('images/tulips.png', ui.onLoad);
sequencer.loadImage("images/tulips.png", ui.onLoad);
}
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)
window.location = '/';
};
window.location = "/";
}
$('#addStep select').on('change', ui.selectNewStepUi);
$('#addStep #add-step-btn').on('click', ui.addStepUi);
$('#resetButton').on('click', resetSequence);
$("#addStep select").on("change", ui.selectNewStepUi);
$("#addStep #add-step-btn").on("click", ui.addStepUi);
$("#resetButton").on("click",resetSequence);
//Module button radio selection
$('.radio-group .radio').on('click', function() {
$('.radio-group .radio').on("click", function() {
$(this).parent().find('.radio').removeClass('selected');
$(this).addClass('selected');
newStep = $(this).attr('data-value');
//$("#addStep option[value=" + newStep + "]").attr('selected', 'selected');
$('#addStep select').val(newStep);
$("#addStep select").val(newStep);
ui.selectNewStepUi(newStep);
ui.addStepUi(newStep);
$(this).removeClass('selected');
});
$('#download-btn').click(function() {
$('.step-thumbnail:last()').trigger("click");
return false;
});
function displayMessageOnSaveSequence(){
$('.savesequencemsg').fadeIn();
setTimeout(function() {
$('.savesequencemsg').fadeOut();
}, 1000);
}
$(".savesequencemsg").fadeIn();
setTimeout(function() {
$(".savesequencemsg").fadeOut();
}, 1000);
}
$('body').on('click', 'button.remove', ui.removeStepUi);
$('#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){
result = result + ' (local)';
result = result + " (local)";
sequencer.saveSequence(result, sequencer.toString());
sequencer.loadModules();
displayMessageOnSaveSequence();
@@ -113,11 +118,11 @@ window.onload = function() {
var button = event.target;
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 {
// Select all images from previous steps
var imgs = document.getElementsByClassName('step-thumbnail');
var imgs = document.getElementsByClassName("step-thumbnail");
var imgSrcs = [];
@@ -130,7 +135,7 @@ window.onload = function() {
'gifHeight': imgs[0].height,
'images': imgSrcs,
'frameDuration': 7,
};
}
gifshot.createGIF(options, function(obj) {
if (!obj.error) {
@@ -138,21 +143,21 @@ window.onload = function() {
var image = obj.image;
var animatedImage = document.createElement('img');
animatedImage.id = 'gif_element';
animatedImage.id = "gif_element";
animatedImage.src = image;
var modal = $('#js-download-gif-modal');
$('#js-download-as-gif-button').one('click', function() {
$("#js-download-as-gif-button").one("click", function() {
// Trigger download
download(image, 'index.gif', 'image/gif');
download(image, "index.gif", "image/gif");
// Close modal
modal.modal('hide');
});
})
var gifContainer = document.getElementById('js-download-modal-gif-container');
var gifContainer = document.getElementById("js-download-modal-gif-container");
// Clear previous results
gifContainer.innerHTML = '';
@@ -181,40 +186,40 @@ window.onload = function() {
// image selection and drag/drop handling from examples/lib/imageSelection.js
sequencer.setInputStep({
dropZoneSelector: '#dropzone',
fileInputSelector: '#fileInput',
takePhotoSelector: '#take-photo',
dropZoneSelector: "#dropzone",
fileInputSelector: "#fileInput",
takePhotoSelector: "#take-photo",
onLoad: function onFileReaderLoad(progress) {
var reader = progress.target;
var step = sequencer.steps[0];
var util = intermediateHtmlStepUi(sequencer);
var util= intermediateHtmlStepUi(sequencer);
step.output.src = reader.result;
sequencer.run({ index: 0 });
if(typeof step.options !== 'undefined')
if(typeof step.options !=="undefined")
step.options.step.imgElement.src = reader.result;
else
step.imgElement.src = reader.result;
insertPreview.updatePreviews(reader.result, '#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src, '.insertDiv');
insertPreview.updatePreviews(reader.result,'#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src,'.insertDiv');
},
onTakePhoto: function (url) {
var step = sequencer.steps[0];
step.output.src = url;
sequencer.run({ index: 0 });
if(typeof step.options !== 'undefined')
if(typeof step.options !=="undefined")
step.options.step.imgElement.src = url;
else
step.imgElement.src = url;
insertPreview.updatePreviews(url, '#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src, '.insertDiv');
insertPreview.updatePreviews(url,'#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src,'.insertDiv');
}
});
setupCache();
if (urlHash.getUrlHashParameter('src')) {
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'), '#addStep');
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'),'#addStep');
} 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

View File

@@ -9,16 +9,11 @@
<meta name="theme-color" content="#428bca">
<link rel="icon" sizes="192x192" href="../icons/ic_192.png">
<link rel="manifest" href="manifest.json">
<!--Adding meta Tag for search engine optimisation-->
<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.">
<meta property="og:site_name" content="sequencer.publiclab.org">
<meta property="og:url" content="https://sequencer.publiclab.org">
<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">
<!--Adding meta Tag for search engine optimisation-->
<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.">
<meta property="og:site_name" content="sequencer.publiclab.org">
<meta property="og:url" content="https://sequencer.publiclab.org">
<meta property="og:title" content="Image Sequencer">
<title>Image Sequencer</title>
@@ -27,13 +22,12 @@
<script src="../src/ui/prepareDynamic.js"></script>
<script src="../dist/image-sequencer.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: -->
<script src="../node_modules/imgareaselect/jquery.imgareaselect.dev.js"></script>
<script src="../node_modules/gifshot/dist/gifshot.min.js" type="text/javascript"></script>
<!-- Download.js for large files -->
<script src="../node_modules/downloadjs/download.min.js" type="text/javascript" />
<script src="../node_modules/downloadjs/download.min.js" type="text/javascript"/>
<script src="lib/scrollToTop.js"></script>
<script src="../node_modules/selectize/dist/js/standalone/selectize.min.js"></script>
@@ -42,14 +36,10 @@
<body>
<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 href="../node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="../node_modules/selectize/dist/css/selectize.default.css" rel="stylesheet">
<!-- 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 rel="stylesheet" href="demo.css">
@@ -58,8 +48,7 @@
<header class="text-center">
<h1><a href="/" target='_blank' class="name-header">Image Sequencer</a></h1>
<p>
A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original
image, it
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.
<a href="https://publiclab.org/image-sequencer">Learn more</a>
</p>
@@ -68,7 +57,7 @@
<a href="https://github.com/publiclab/image-sequencer">
<i class="fa fa-github"></i>
</a>
by <a href="https://publiclab.org" title="Publiclab Website"><i class="fa fa-globe"></i> Publiclab</a>
by <a href= "https://publiclab.org" title = "Publiclab Website"><i class = "fa fa-globe"></i> Publiclab</a>
</p>
</header>
@@ -79,7 +68,7 @@
<center>
<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>
<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="close" style="display:none" class="btn btn-default btn-md">Close</a>
<canvas id="canvas" width="400" height="300" style="display:none"></canvas>
@@ -91,147 +80,143 @@
</section>
<hr />
<p class="alert alert-success savesequencemsg">Saved Sequence Success. Sequence can be found among other modules.
</p>
<div class="row">
<div class="col-sm-8">
<section id="addStep" class="panel panel-primary">
<div class="form-inline">
<div class="panel-body">
<div style="display:flex; justify-content:center;">
<p class = "alert alert-success savesequencemsg">Saved Sequence Success. Sequence can be found among other modules.</p>
<div class="row">
<div class="col-sm-8">
<section id="addStep" class="panel panel-primary">
<div class="form-inline">
<div class="panel-body">
<div style="display:flex; justify-content:center;">
</div>
<p class="info">Select a new module to add to your sequence.</p>
<div class="row center-align radio-group">
<div>
<div class="radio" data-value="resize">
<i class="fa fa-arrows-alt fa-4x i-over"></i>
</div>
<p class="info">Select a new module to add to your sequence.</p>
<div class="row center-align radio-group">
<div>
<div class="radio" data-value="resize">
<i class="fa fa-arrows-alt fa-4x i-over"></i>
</div>
<p>Resize</p>
</div>
<div>
<div class="radio" data-value="brightness">
<i class="fa fa-sun-o fa-4x i-over"></i>
</div>
<p>Brightness</p>
</div>
<div>
<div class="radio" data-value="contrast">
<i class="fa fa-adjust fa-4x i-over"></i>
</div>
<p>Contrast</p>
</div>
<div>
<div class="radio" data-value="saturation">
<i class="fa fa-tint fa-4x i-over i-small"></i>
</div>
<p>Saturation</p>
</div>
<div>
<div class="radio" data-value="rotate">
<i class="fa fa-rotate-right fa-4x i-over"></i>
</div>
<p>Rotate</p>
</div>
<div>
<div class="radio" data-value="crop">
<i class="fa fa-crop fa-4x i-over"></i>
</div>
<p>Crop</p>
</div>
<p>Resize</p>
</div>
<div>
<div class="radio" data-value="brightness">
<i class="fa fa-sun-o fa-4x i-over"></i>
</div>
<div class="row center-align">
<div class="col-md-8">
<select id="selectStep">
<!-- The default null selection has been appended manually in demo.js
This is because the options in select are overritten when options are appended.-->
</select>
</div>
<div class="col-md-4">
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button></div>
<p>Brightness</p>
</div>
<div>
<div class="radio" data-value="contrast">
<i class="fa fa-adjust fa-4x i-over"></i>
</div>
<div class="row center-align">
<button id="resetButton" class="btn btn-default btn-lg"
style=" margin: 20px 35px 0px 35px; width:100%;">Clear All Steps</button>
<p>Contrast</p>
</div>
<div>
<div class="radio" data-value="saturation">
<i class="fa fa-tint fa-4x i-over i-small"></i>
</div>
<p>Saturation</p>
</div>
<div>
<div class="radio" data-value="rotate">
<i class="fa fa-rotate-right fa-4x i-over"></i>
</div>
<p>Rotate</p>
</div>
<div>
<div class="radio" data-value="crop">
<i class="fa fa-crop fa-4x i-over"></i>
</div>
<p>Crop</p>
</div>
</div>
</section>
<div class="modal fade" id="js-download-gif-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Your gif is ready</h4>
</div>
<div class="modal-body">
<div id="js-download-modal-gif-container">
<!-- Gif should appear here -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Done</button>
<button id="js-download-as-gif-button" class="btn btn-primary">Download</button>
</div>
<div class="row center-align">
<div class="col-md-8">
<select id="selectStep" >
<!-- The default null selection has been appended manually in demo.js
This is because the options in select are overritten when options are appended.-->
</select>
</div>
<div class="col-md-4">
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button></div>
</div>
<div class="row center-align">
<button id="resetButton" class="btn btn-default btn-lg" style=" margin: 20px 35px 0px 35px; width:100%;">Clear All Steps</button>
</div>
</div>
</div>
</section>
<div class="modal fade" id="js-download-gif-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Your gif is ready</h4>
</div>
<div class="modal-body">
<div id="js-download-modal-gif-container">
<!-- Gif should appear here -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Done</button>
<button id="js-download-as-gif-button" class="btn btn-primary">Download</button>
</div>
</div>
</div>
<div class="col-sm-4">
<section id="dwnld" class="panel panel-primary">
<div class="form-inline">
<div class="panel-body">
<div style="text-align:center;">
<h2 style="margin-top:20px">Save</h2>
<select class="form-control input-md" id="selectSaveOption" style="margin-top:20px">
<option>Save as PNG</option>
<option>Save as GIF (all steps)</option>
<option>Save sequence</option>
<option>Save sequence string</option>
</select>
<p><button id="saveButton" class="btn btn-primary btn-lg save-button">Save</button></p>
<p><button class="btn btn-default btn-lg js-view-as-gif" id="gif">Preview GIF</button></p>
</div>
</div>
</div>
</section>
</div>
</div>
<footer>
<hr style="margin:20px;">
<center><button class="btn btn-default btn-sm" id="clear-cache">Clear offline cache</button></center>
<div class="row">
<div class="col-md-6">
<h2>Need Help?</h2>
<p>
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer/issues">Ask a question</a>
<a class="btn btn-default" href="https://publiclab.org/chat">Ask in our chatroom</a>
</p>
</div>
<div class="col-md-6">
<h2>Improve this tool</h2>
<p>
This is an open source toolkit which you can help improve on Github
</p>
<p>
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer">View the code &raquo;</a>
</p>
</div>
<div class="col-sm-4">
<section id="dwnld" class="panel panel-primary">
<div class="form-inline">
<div class="panel-body">
<div style="text-align:center;">
<h2 style="margin-top:20px">Save</h2>
<select class="form-control input-md" id="selectSaveOption" style="margin-top:20px">
<option>Save as PNG</option>
<option>Save as GIF (all steps)</option>
<option>Save sequence</option>
<option>Save sequence string</option>
</select>
<p><button id="saveButton" class="btn btn-primary btn-lg save-button">Save</button></p>
<p><button class="btn btn-default btn-lg js-view-as-gif" id="gif">Preview GIF</button></p>
</div>
</div>
</div>
</footer>
</section>
</div>
</div>
<button id="move-up"><i class="fa fa-arrow-circle-o-up"></i></button>
<footer>
<hr style="margin:20px;"><center><button class="btn btn-default btn-sm" id="clear-cache">Clear offline cache</button></center>
<div class="row">
<div class="col-md-6">
<h2>Need Help?</h2>
<p>
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer/issues">Ask a question</a>
<a class="btn btn-default" href="https://publiclab.org/chat">Ask in our chatroom</a>
</p>
</div>
<div class="col-md-6">
<h2>Improve this tool</h2>
<p>
This is an open source toolkit which you can help improve on Github
</p>
<p>
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer">View the code &raquo;</a>
</p>
</div>
</div>
</footer>
<script type="text/javascript">
$(function () {
var sequencer;
})
</script>
<button id="move-up"><i class="fa fa-arrow-circle-o-up"></i></button>
<script type="text/javascript">
$(function() {
var sequencer;
})
</script>
</body>

View File

@@ -4,11 +4,11 @@ var setupCache = function() {
.then(function(registration) {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
console.log(installingWorker);
console.log(installingWorker)
if (installingWorker.state === 'installed') {
location.reload();
}
};
}
console.log('Registration successful, scope is:', registration.scope);
})
.catch(function(error) {
@@ -19,12 +19,12 @@ var setupCache = function() {
if ('serviceWorker' in navigator) {
caches.keys().then(function(cacheNames) {
cacheNames.forEach(function(cacheName) {
$('#clear-cache').append(' ' + cacheName);
$("#clear-cache").append(" " + cacheName);
});
});
}
$('#clear-cache').click(function() {
$("#clear-cache").click(function() {
if ('serviceWorker' in navigator) {
caches.keys().then(function(cacheNames) {
cacheNames.forEach(function(cacheName) {
@@ -34,6 +34,6 @@ var setupCache = function() {
}
location.reload();
});
};
}
module.exports = setupCache;

View File

@@ -2,52 +2,51 @@ var urlHash = require('./urlHash.js');
function DefaultHtmlSequencerUi(_sequencer, options) {
options = options || {};
var addStepSel = options.addStepSel = options.addStepSel || '#addStep';
var removeStepSel = options.removeStepSel = options.removeStepSel || 'button.remove';
var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep';
var addStepSel = options.addStepSel = options.addStepSel || "#addStep";
var removeStepSel = options.removeStepSel = options.removeStepSel || "button.remove";
var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep";
function onLoad() {
importStepsFromUrlHash();
if ($('#selectStep').val() === 'none')
$(addStepSel + ' #add-step-btn').prop('disabled', true);
handleSaveSequence();
if ($('#selectStep').val()==='none')
$(addStepSel + " #add-step-btn").prop("disabled", true);
handleSaveSequence();
}
// look up needed steps from Url Hash:
function importStepsFromUrlHash() {
var hash = urlHash.getUrlHashParameter('steps');
var hash = urlHash.getUrlHashParameter("steps");
if (hash) {
_sequencer.importString(hash);
_sequencer.run({ index: 0 });
}
urlHash.setUrlHashParameter('steps', sequencer.toString());
urlHash.setUrlHashParameter("steps", sequencer.toString());
}
function selectNewStepUi() {
var m = $(addStepSel + ' select').val();
var m = $(addStepSel + " select").val();
if(!m) m = arguments[0];
$(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description);
$(addStepSel + ' #add-step-btn').prop('disabled', false);
$(addStepSel + " .info").html(_sequencer.modulesInfo(m).description);
$(addStepSel + " #add-step-btn").prop("disabled", false);
}
function removeStepUi() {
var index = $(removeStepSel).index(this) + 1;
sequencer.removeSteps(index).run({ index: index - 1 });
// remove from URL hash too
urlHash.setUrlHashParameter('steps', sequencer.toString());
urlHash.setUrlHashParameter("steps", sequencer.toString());
//disable save-sequence button if all steps are removed
handleSaveSequence();
}
function addStepUi() {
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];
if ($(addStepSel + " select").val() == "none") return;
var newStepName = $(addStepSel + " select").val();
if(!newStepName) newStepName = arguments[0]
/*
* after adding the step we run the sequencer from defined step
* and since loadImage is not a part of the drawarray the step lies at current
@@ -56,28 +55,28 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
var sequenceLength = 1;
if (sequencer.sequences[newStepName]) {
sequenceLength = sequencer.sequences[newStepName].length;
} else if (sequencer.modules[newStepName][1]['length']) {
sequenceLength = sequencer.modules[newStepName][1]['length'];
} else if (sequencer.modules[newStepName][1]["length"]) {
sequenceLength = sequencer.modules[newStepName][1]["length"];
}
_sequencer
.addSteps(newStepName, options)
.run({ index: _sequencer.steps.length - sequenceLength - 1 });
$(addStepSel + ' .info').html('Select a new module to add to your sequence.');
$(addStepSel + ' select').val('none');
$(addStepSel + " .info").html("Select a new module to add to your sequence.");
$(addStepSel + " select").val("none");
//enable save-sequence button if disabled initially
handleSaveSequence();
// add to URL hash too
urlHash.setUrlHashParameter('steps', _sequencer.toString());
urlHash.setUrlHashParameter("steps", _sequencer.toString())
}
function handleSaveSequence(){
var stepCount = sequencer.steps.length;
if(stepCount < 2)
$(' #save-seq').prop('disabled', true);
var stepCount=sequencer.steps.length;
if(stepCount<2)
$(" #save-seq").prop("disabled", true);
else
$(' #save-seq').prop('disabled', false);
$(" #save-seq").prop("disabled", false);
}
return {
@@ -86,7 +85,7 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
selectNewStepUi: selectNewStepUi,
removeStepUi: removeStepUi,
addStepUi: addStepUi
};
}
}
module.exports = DefaultHtmlSequencerUi;

View File

@@ -16,8 +16,8 @@ var mapHtmlTypes = require('./mapHtmltypes');
function DefaultHtmlStepUi(_sequencer, options) {
options = options || {};
var stepsEl = options.stepsEl || document.querySelector('#steps');
var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep';
var stepsEl = options.stepsEl || document.querySelector("#steps");
var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep";
function onSetup(step, stepOptions) {
if (step.options && step.options.description)
@@ -29,8 +29,8 @@ function DefaultHtmlStepUi(_sequencer, options) {
<div class="panel panel-default">\
<div class="panel-heading">\
<div class="trash-container pull-right"></div>\
<h3 class="panel-title">' +
'<span class="toggle">' + step.name + ' <span class="caret toggleIcon rotated"></span>\
<h3 class="panel-title">' +
'<span class="toggle">' +step.name + ' <span class="caret toggleIcon rotated"></span>\
<span class="load-spin pull-right" style="display:none;padding:1px 8px;"><i class="fa fa-circle-o-notch fa-spin"></i></span>\
</h3>\
</div>\
@@ -39,7 +39,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
<div class="row step">\
<div class="col-md-4 details container-fluid">\
<div class="cal collapse in"><p>' +
'<i>' + (step.description || '') + '</i>' +
'<i>' + (step.description || "") + '</i>' +
'</p></div>\
</div>\
<div class="col-md-8 cal collapse in step-column">\
@@ -65,10 +65,10 @@ function DefaultHtmlStepUi(_sequencer, options) {
var util = intermediateHtmlStepUi(_sequencer, step);
var parser = new DOMParser();
step.ui = parser.parseFromString(step.ui, 'text/html');
step.ui = step.ui.querySelector('div.container-fluid');
step.linkElements = step.ui.querySelectorAll('a');
step.imgElement = step.ui.querySelector('a img.img-thumbnail');
step.ui = parser.parseFromString(step.ui, "text/html");
step.ui = step.ui.querySelector("div.container-fluid");
step.linkElements = step.ui.querySelectorAll("a");
step.imgElement = step.ui.querySelector("a img.img-thumbnail");
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
var inputs = _sequencer.modulesInfo(step.name).inputs;
@@ -77,132 +77,111 @@ function DefaultHtmlStepUi(_sequencer, options) {
for (var paramName in merged) {
var isInput = inputs.hasOwnProperty(paramName);
var html = '';
var html = "";
var inputDesc = isInput ? mapHtmlTypes(inputs[paramName]) : {};
if (!isInput) {
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 + '">';
for (var option in inputDesc.values) {
html += '<option>' + inputDesc.values[option] + '</option>';
html += "<option>" + inputDesc.values[option] + "</option>";
}
html += '</select>';
}
else {
html += "</select>";
} else {
let paramVal = step.options[paramName] || inputDesc.default;
html =
'<input class="form-control target" type="' +
inputDesc.type +
'" name="' +
paramName +
'" value="' +
paramVal +
'" placeholder ="' +
(inputDesc.placeholder || "");
if (inputDesc.id == 'color-picker') { // separate input field for color-picker
if (inputDesc.type.toLowerCase() == "range") {
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 =
'<input class="form-control target" type="' +
inputDesc.type +
'" name="' +
paramName +
'" value="' +
paramVal +
'" placeholder ="' +
(inputDesc.placeholder || '');
if (inputDesc.type.toLowerCase() == 'range') {
html +=
'"min="' +
inputDesc.min +
'"max="' +
inputDesc.max +
'"step="' +
(inputDesc.step ? inputDesc.step : 1) + '">' + '<span>' + paramVal + '</span>';
'"min="' +
inputDesc.min +
'"max="' +
inputDesc.max +
'"step="' +
(inputDesc.step ? inputDesc.step : 1)+ '">' + '<span>' + paramVal + '</span>';
}
else html += '">';
}
else html += '">';
}
var div = document.createElement('div');
div.className = 'row';
div.setAttribute('name', paramName);
var div = document.createElement("div");
div.className = "row";
div.setAttribute("name", paramName);
var description = inputs[paramName].desc || paramName;
div.innerHTML =
'<div class=\'det cal collapse in\'>\
<label for=\'' +
"<div class='det cal collapse in'>\
<label for='" +
paramName +
'\'>' +
"'>" +
description +
'</label>\
' +
"</label>\
" +
html +
'\
</div>';
step.ui.querySelector('div.details').appendChild(div);
"\
</div>";
step.ui.querySelector("div.details").appendChild(div);
}
$(step.ui.querySelector('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>'
);
$(step.ui.querySelector('div.panel-footer')).prepend(
$(step.ui.querySelector("div.panel-footer")).prepend(
'<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>\
<button class="pull-right btn btn-default btn-sm download-btn" style="margin-right:2px" >\
<i class="fa fa-download"></i>\
<span class="insert-text"><i class="fa fa-plus"></i> Insert Step</span><span class="no-insert-text" style="display:none">Close</span>\
</button>'
);
);
}
if (step.name != 'load-image') {
if (step.name != "load-image") {
step.ui
.querySelector('div.trash-container')
.querySelector("div.trash-container")
.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');});
$(step.ui.querySelectorAll('.insert-step')).on('click', function() { util.insertStep(step.ID); });
$(step.ui.querySelectorAll(".remove")).on('click', function() {notify('Step Removed','remove-notification')});
$(step.ui.querySelectorAll(".insert-step")).on('click', function() { util.insertStep(step.ID) });
// Insert the step's UI in the right place
if (stepOptions.index == _sequencer.steps.length) {
stepsEl.appendChild(step.ui);
$('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true);
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(1) .insert-step").prop('disabled',true);
if($("#steps .step-container:nth-last-child(2)"))
$("#steps .step-container:nth-last-child(2) .insert-step").prop('disabled',false);
} else {
stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]);
}
}
else {
$('#load-image').append(step.ui);
$("#load-image").append(step.ui);
}
$(step.ui.querySelector('.toggle')).on('click', () => {
$(step.ui.querySelector(".toggle")).on("click", () => {
$(step.ui.querySelector('.toggleIcon')).toggleClass('rotated');
$(step.ui.querySelectorAll('.cal')).collapse('toggle');
$(step.ui.querySelectorAll(".cal")).collapse('toggle');
});
$(step.imgElement).on('mousemove', _.debounce(() => imageHover(step), 150));
$(step.imgElement).on('click', (e) => {e.preventDefault(); });
$(step.ui.querySelectorAll('#color-picker')).colorpicker();
$(step.imgElement).on("mousemove", _.debounce(() => imageHover(step), 150));
function saveOptions(e) {
e.preventDefault();
if (optionsChanged){
$(step.ui.querySelector('div.details'))
.find('input,select')
$(step.ui.querySelector("div.details"))
.find("input,select")
.each(function(i, input) {
$(input)
.data('initValue', $(input).val())
.data('hasChangedBefore', false);
step.options[$(input).attr('name')] = $(input).val();
step.options[$(input).attr("name")] = $(input).val();
});
_sequencer.run({ index: step.index - 1 });
// modify the url hash
urlHash.setUrlHashParameter('steps', _sequencer.toString());
urlHash.setUrlHashParameter("steps", _sequencer.toString())
// disable the save button
$(step.ui.querySelector('.btn-save')).prop('disabled', true);
optionsChanged = false;
@@ -219,7 +198,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
return inputChanged;
}
var
var
changedInputs = 0,
optionsChanged = false;
$(step.ui.querySelector('.input-form')).on('submit', saveOptions);
@@ -227,7 +206,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
$(input)
.data('initValue', $(input).val())
.data('hasChangedBefore', false)
.on('input change', function() {
.on('input', function() {
$(this)
.focus()
.data('hasChangedBefore',
@@ -235,32 +214,32 @@ function DefaultHtmlStepUi(_sequencer, options) {
$(this).val(),
$(this).data('initValue'),
$(this).data('hasChangedBefore')
)
);
});
});
)
)
})
})
$('input[type="range"]').on('input', function() {
$(this).next().html($(this).val());
});
$(this).next().html($(this).val());
})
}
function onDraw(step) {
$(step.ui.querySelector('.load')).show();
$(step.ui.querySelector('img')).hide();
$(step.ui.querySelectorAll('.load-spin')).show();
$(step.ui.querySelector(".load")).show();
$(step.ui.querySelector("img")).hide();
$(step.ui.querySelectorAll(".load-spin")).show();
}
function onComplete(step) {
$(step.ui.querySelector('img')).show();
$(step.ui.querySelectorAll('.load-spin')).hide();
$(step.ui.querySelector('.load')).hide();
$(step.ui.querySelector("img")).show();
$(step.ui.querySelectorAll(".load-spin")).hide();
$(step.ui.querySelector(".load")).hide();
step.imgElement.src = (step.name == 'load-image') ? step.output.src : step.output;
var imgthumbnail = step.ui.querySelector('.img-thumbnail');
step.imgElement.src = (step.name == "load-image") ? step.output.src : step.output;
var imgthumbnail = step.ui.querySelector(".img-thumbnail");
for (let index = 0; index < step.linkElements.length; index++) {
if (step.linkElements[index].contains(imgthumbnail))
step.linkElements[index].href = step.imgElement.src;
@@ -268,24 +247,14 @@ function DefaultHtmlStepUi(_sequencer, options) {
// TODO: use a generalized version of this
function fileExtension(output) {
return output.split('/')[1].split(';')[0];
return output.split("/")[1].split(";")[0];
}
$(step.ui.querySelectorAll('.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');
element.setAttribute('href', step.linkElements[index].href);
element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src));
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
});
step.linkElements[index].download = step.name + "." + fileExtension(step.imgElement.src);
step.linkElements[index].target = "_blank";
}
// fill inputs with stored step options
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
@@ -293,11 +262,11 @@ function DefaultHtmlStepUi(_sequencer, options) {
var outputs = _sequencer.modulesInfo(step.name).outputs;
for (var i in inputs) {
if (step.options[i] !== undefined) {
if (inputs[i].type.toLowerCase() === 'input')
if (inputs[i].type.toLowerCase() === "input")
$(step.ui.querySelector('div[name="' + i + '"] input'))
.val(step.options[i])
.data('initValue', step.options[i]);
if (inputs[i].type.toLowerCase() === 'select')
if (inputs[i].type.toLowerCase() === "select")
$(step.ui.querySelector('div[name="' + i + '"] select'))
.val(step.options[i])
.data('initValue', step.options[i]);
@@ -315,24 +284,24 @@ function DefaultHtmlStepUi(_sequencer, options) {
var img = $(step.imgElement);
img.mousemove(function(e) {
img.mousemove(function(e) {
var canvas = document.createElement('canvas');
canvas.width = img.width();
canvas.height = img.height();
var context = canvas.getContext('2d');
context.drawImage(this, 0, 0);
context.drawImage(this,0,0);
var offset = $(this).offset();
var xPos = e.pageX - offset.left;
var yPos = e.pageY - offset.top;
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) {
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();
}
@@ -340,17 +309,17 @@ function DefaultHtmlStepUi(_sequencer, options) {
return step.imgElement;
}
function notify(msg, id){
if ($('#' + id).length == 0) {
function notify(msg,id){
if ($('#'+id).length == 0) {
var notification = document.createElement('span');
notification.innerHTML = ' <i class="fa fa-info-circle" aria-hidden="true"></i> ' + msg ;
notification.id = id;
notification.classList.add('notification');
notification.classList.add("notification");
$('body').append(notification);
}
$('#' + id).fadeIn(500).delay(200).fadeOut(500);
$('#'+id).fadeIn(500).delay(200).fadeOut(500);
}
@@ -359,16 +328,17 @@ function DefaultHtmlStepUi(_sequencer, options) {
onSetup: onSetup,
onComplete: onComplete,
onRemove: onRemove,
onDraw: onDraw,
onDraw: onDraw,
notify: notify,
imageHover: imageHover
};
}
}
if(typeof window === 'undefined'){
module.exports = {
if(typeof window === "undefined"){
module.exports={
DefaultHtmlStepUi: DefaultHtmlStepUi
};
}
}
module.exports = DefaultHtmlStepUi;

View File

@@ -1,55 +1,55 @@
function generatePreview(previewStepName, customValues, path, selector) {
var previewSequencer = ImageSequencer();
function insertPreview(src) {
var img = document.createElement('img');
img.classList.add('img-thumbnail');
img.classList.add('no-border');
img.src = src;
$(img).css('max-width', '200%');
$(img).css('transform', 'translateX(-20%)');
$(selector + ' .radio-group').find('div').each(function() {
if ($(this).find('div').attr('data-value') === previewStepName) {
$(this).find('div').append(img);
var previewSequencer = ImageSequencer();
function insertPreview(src) {
var img = document.createElement('img');
img.classList.add('img-thumbnail')
img.classList.add('no-border');
img.src = src;
$(img).css("max-width", "200%");
$(img).css("transform", "translateX(-20%)");
$(selector + ' .radio-group').find('div').each(function() {
if ($(this).find('div').attr('data-value') === previewStepName) {
$(this).find('div').append(img);
}
});
}
function loadPreview() {
if (previewStepName === "crop") {
previewSequencer.addSteps(previewStepName, customValues).run(insertPreview);
}
else {
previewSequencer.addSteps(previewStepName, { [previewStepName]: customValues }).run(insertPreview);
}
}
previewSequencer.loadImage(path, loadPreview);
}
function updatePreviews(src, selector) {
$(selector+' img').remove();
var previewSequencerSteps = {
"resize": "125%",
"brightness": "175",
"saturation": "0.5",
"rotate": 90,
"contrast": 90,
"crop": {
"x": 0,
"y": 0,
"w": "(50%)",
"h": "(50%)",
"noUI": true
}
}
Object.keys(previewSequencerSteps).forEach(function (step, index) {
generatePreview(step, Object.values(previewSequencerSteps)[index], src, selector);
});
}
function loadPreview() {
if (previewStepName === 'crop') {
previewSequencer.addSteps(previewStepName, customValues).run(insertPreview);
}
else {
previewSequencer.addSteps(previewStepName, { [previewStepName]: customValues }).run(insertPreview);
}
}
previewSequencer.loadImage(path, loadPreview);
}
function updatePreviews(src, selector) {
$(selector + ' img').remove();
var previewSequencerSteps = {
'resize': '125%',
'brightness': '175',
'saturation': '0.5',
'rotate': 90,
'contrast': 90,
'crop': {
'x': 0,
'y': 0,
'w': '(50%)',
'h': '(50%)',
'noUI': true
}
};
Object.keys(previewSequencerSteps).forEach(function (step, index) {
generatePreview(step, Object.values(previewSequencerSteps)[index], src, selector);
});
}
module.exports = {
generatePreview : generatePreview,
updatePreviews : updatePreviews
};
}

View File

@@ -1,5 +1,5 @@
var urlHash = require('./urlHash.js'),
insertPreview = require('./insertPreview.js');
insertPreview = require('./insertPreview.js');
function IntermediateHtmlStepUi(_sequencer, step, options) {
function stepUI() {
@@ -66,52 +66,52 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
function selectNewStepUi() {
var insertSelect = $(step.ui.querySelector('.insert-step-select'));
var insertSelect = $(step.ui.querySelector('.insert-step-select'))
var m = insertSelect.val();
$(step.ui.querySelector('.insertDiv .info')).html(_sequencer.modulesInfo(m).description);
$(step.ui.querySelector('.insertDiv .add-step-btn')).prop('disabled', false);
$(step.ui.querySelector('.insertDiv .add-step-btn')).prop("disabled", false);
}
var toggleDiv = function(callback = function(){}){
$(step.ui.querySelector('.insertDiv')).collapse('toggle');
if ($(step.ui.querySelector('.insert-text')).css('display') != 'none'){
$(step.ui.querySelector('.insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, callback);});
if ($(step.ui.querySelector('.insert-text')).css('display') != "none"){
$(step.ui.querySelector('.insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, callback)})
}
else {
$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.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) {
var modulesInfo = _sequencer.modulesInfo();
var parser = new DOMParser();
var addStepUI = stepUI();
addStepUI = parser.parseFromString(addStepUI, 'text/html').querySelector('div');
addStepUI = parser.parseFromString(addStepUI, "text/html").querySelector("div")
if ($(step.ui.querySelector('.insertDiv')).length > 0){
toggleDiv();
}
else {
step.ui
.querySelector('div.step')
.insertAdjacentElement('afterend',
addStepUI
);
.querySelector("div.step")
.insertAdjacentElement('afterend',
addStepUI
);
toggleDiv(function(){
insertPreview.updatePreviews(step.output, '.insertDiv');
});
}
$(step.ui.querySelector('.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.ui.querySelector('.insert-step-select'));
insertStepSelect.html('');
insertStepSelect.html("");
// Add modules to the insertStep dropdown
for (var m in modulesInfo) {
if (modulesInfo[m] !== undefined)
insertStepSelect.append(
'<option value="' + m + '">' + modulesInfo[m].name + '</option>'
'<option value="' + m + '">' + modulesInfo[m].name + "</option>"
);
}
insertStepSelect.selectize({
@@ -120,7 +120,7 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
$(step.ui.querySelector('.inserDiv .add-step-btn')).prop('disabled', true);
insertStepSelect.append('<option value="" disabled selected>Select a Module</option>');
$(step.ui.querySelector('.insertDiv .radio-group .radio')).on('click', function () {
$(step.ui.querySelector('.insertDiv .radio-group .radio')).on("click", function () {
$(this).parent().find('.radio').removeClass('selected');
$(this).addClass('selected');
newStep = $(this).attr('data-value');
@@ -130,34 +130,34 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
$(this).removeClass('selected');
});
insertStepSelect.on('change', selectNewStepUi);
$(step.ui.querySelector('.insertDiv .add-step-btn')).on('click', function () { insert(id); });
};
$(step.ui.querySelector('.insertDiv .add-step-btn')).on('click', function () { insert(id) });
}
function insert(id) {
options = options || {};
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();
var sequenceLength = 1;
if (sequencer.sequences[newStepName]) {
sequenceLength = sequencer.sequences[newStepName].length;
} else if (sequencer.modules[newStepName][1]['length']) {
sequenceLength = sequencer.modules[newStepName][1]['length'];
} else if (sequencer.modules[newStepName][1]["length"]) {
sequenceLength = sequencer.modules[newStepName][1]["length"];
}
_sequencer
.insertSteps(id + 1, newStepName).run({ index: id });
// add to URL hash too
urlHash.setUrlHashParameter('steps', _sequencer.toString());
urlHash.setUrlHashParameter("steps", _sequencer.toString());
}
return {
insertStep
};
}
}
module.exports = IntermediateHtmlStepUi;

View File

@@ -1,24 +1,24 @@
function mapHtmlTypes(inputInfo){
var htmlType;
switch(inputInfo.type.toLowerCase()){
case 'integer':
htmlType = inputInfo.min != undefined ? 'range' : 'number';
break;
case 'string':
htmlType = 'text';
break;
case 'select':
htmlType = 'select';
break;
case 'percentage':
htmlType = 'number';
break;
case 'float':
htmlType = inputInfo.min != undefined ? 'range' : 'text';
break;
default:
htmlType = 'text';
break;
case 'integer':
htmlType = inputInfo.min != undefined ? 'range' : 'number';
break;
case 'string':
htmlType = 'text';
break;
case 'select':
htmlType = 'select';
break;
case 'percentage':
htmlType = 'number';
break;
case 'float':
htmlType = inputInfo.min != undefined ? 'range' : 'text';
break;
default:
htmlType = 'text';
break;
}
var response = inputInfo;
response.type = htmlType;

View File

@@ -42,8 +42,8 @@ function setUrlHashParameter(param, value) {
}
module.exports = {
getUrlHashParameter: getUrlHashParameter,
setUrlHashParameter: setUrlHashParameter,
getUrlHashParameters: getUrlHashParameters,
setUrlHashParameters: setUrlHashParameters
};
getUrlHashParameter: getUrlHashParameter,
setUrlHashParameter: setUrlHashParameter,
getUrlHashParameters: getUrlHashParameters,
setUrlHashParameters: setUrlHashParameters
}

View File

@@ -17,7 +17,7 @@ self.addEventListener('activate', function(e) {
})
);
})
);
);
});
self.addEventListener('fetch', function(event) {
@@ -25,7 +25,7 @@ self.addEventListener('fetch', function(event) {
caches.open(staticCacheName).then(function(cache) {
return cache.match(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());
return response;
});

View File

@@ -1,14 +1,14 @@
#!/usr/bin/env node
require('./src/ImageSequencer');
sequencer = ImageSequencer({ ui: true });
var fs = require('fs');
sequencer = ImageSequencer({ ui: false });
var fs = require('fs')
var program = require('commander');
var utils = require('./src/CliUtils');
var utils = require('./src/CliUtils')
var saveSequence = require('./src/cli/saveSequence.js');
var installModule = require('./src/cli/installModule.js');
var sequencerSteps = require('./src/cli/sequencerSteps.js');
var saveSequence = require('./src/cli/saveSequence.js')
var installModule = require('./src/cli/installModule.js')
var sequencerSteps = require('./src/cli/sequencerSteps.js')
function exit(message) {
console.error(message);
@@ -16,39 +16,39 @@ function exit(message) {
}
program
.version('0.1.0')
.option('-i, --image [PATH/URL]', 'Input image URL')
.option('-s, --step [step-name]', 'Name of the step to be added.')
.option('-o, --output [PATH]', 'Directory where output will be stored.')
.option('-b, --basic', 'Basic mode outputs only final image')
.option('-c, --config [Object]', 'Options for the step')
.option('--save-sequence [string]', 'Name space separated with Stringified sequence')
.option('--install-module [string]', 'Module name space seaprated npm package name')
.version("0.1.0")
.option("-i, --image [PATH/URL]", "Input image URL")
.option("-s, --step [step-name]", "Name of the step to be added.")
.option("-o, --output [PATH]", "Directory where output will be stored.")
.option("-b, --basic", "Basic mode outputs only final image")
.option("-c, --config [Object]", "Options for the step")
.option("--save-sequence [string]", "Name space separated with Stringified sequence")
.option('--install-module [string]', "Module name space seaprated npm package name")
.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 {
// Parse step into an array to allow for multiple steps.
if (!program.step) exit('No steps passed');
program.step = program.step.split(' ');
if (!program.step) exit("No steps passed");
program.step = program.step.split(" ");
// 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.
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.
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.
program.output = program.output || './output/';
program.output = program.output || "./output/";
// Set sequencer to log module outputs, if any.
sequencer.setUI({
@@ -57,19 +57,19 @@ else {
step.info = sequencer.modulesInfo(step.name);
for (var output in step.info.outputs) {
console.log('[' + program.step + ']: ' + output + ' = ' + step[output]);
console.log("[" + program.step + "]: " + output + " = " + step[output]);
}
},
notify: function(msg) {
console.log('\x1b[36m%s\x1b[0m', '🌟 ' + msg);
console.log('\x1b[36m%s\x1b[0m','🌟 '+msg);
}
});
// Finally, if everything is alright, load the image, add the steps and run the sequencer.
sequencer.loadImages(program.image, function() {
console.warn(
'\x1b[33m%s\x1b[0m',
'Please wait \n output directory generated will be empty until the execution is complete'
"\x1b[33m%s\x1b[0m",
"Please wait \n output directory generated will be empty until the execution is complete"
);
//Generate the Output Directory
@@ -82,7 +82,7 @@ else {
outputFilename = null;
}
sequencerSteps(program, sequencer, outputFilename);
sequencerSteps(program, sequencer, outputFilename)
});

3490
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,15 @@
{
"name": "image-sequencer",
"version": "3.5.0",
"version": "3.0.1",
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
"main": "src/ImageSequencer.js",
"scripts": {
"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-ui": "node node_modules/jasmine/bin/jasmine test/spec/*.js",
"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": "jasmine test/spec/*.js",
"setup": "npm i && npm i -g grunt grunt-cli && grunt build",
"start": "grunt serve"
},
"lint-staged": {
"*.js": [
"./node_modules/.bin/eslint --fix",
"git add"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/publiclab/image-sequencer.git"
@@ -30,31 +24,26 @@
"url": "https://github.com/publiclab/image-sequencer/issues"
},
"dependencies": {
"base64-img": "^1.0.4",
"bootstrap": "~3.4.0",
"bootstrap-colorpicker": "^2.5.3",
"buffer": "~5.2.1",
"commander": "^2.11.0",
"data-uri-to-buffer": "^2.0.0",
"downloadjs": "^1.4.7",
"eslint": "^5.16.0",
"fisheyegl": "^0.1.2",
"font-awesome": "~4.7.0",
"geotiff": "^1.0.0-beta.6",
"get-pixels": "~3.3.0",
"gifshot": "^0.4.5",
"glfx": "0.0.4",
"gpu.js": "^2.0.0-rc.12",
"image-sequencer-invert": "^1.0.0",
"imagejs": "0.0.9",
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
"istanbul": "^0.4.5",
"jasmine": "^3.4.0",
"jquery": "^3.3.1",
"jsdom": "^15.0.0",
"jsdom": "^14.0.0",
"jsqr": "^1.1.1",
"lodash": "^4.17.11",
"ndarray": "^1.0.18",
"ndarray-gaussian-filter": "^1.0.0",
"ora": "^3.0.0",
"pace": "0.0.4",
"puppeteer": "^1.14.0",
@@ -62,41 +51,29 @@
"readline-sync": "^1.4.7",
"save-pixels": "~2.3.4",
"selectize": "^0.12.6",
"urify": "^2.1.1",
"webgl-distort": "0.0.2"
"urify": "^2.1.1"
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/plugin-proposal-object-rest-spread": "^7.4.3",
"@babel/plugin-syntax-object-rest-spread": "^7.2.0",
"babelify": "^10.0.0",
"base64-img": "^1.0.4",
"browserify": "16.2.3",
"eslint": "^5.16.0",
"grunt": "^1.0.3",
"grunt-browser-sync": "^2.2.0",
"grunt-browserify": "^5.0.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-uglify-es": "^3.3.0",
"grunt-contrib-watch": "^1.1.0",
"husky": "^2.2.0",
"image-filter-core": "~2.0.2",
"image-filter-threshold": "~2.0.1",
"jasmine-core": "^3.3.0",
"jasmine-jquery": "^2.1.1",
"jasmine-spec-reporter": "^4.2.1",
"lint-staged": "^8.1.6",
"looks-same": "^7.0.0",
"matchdep": "^2.0.0",
"tap-spec": "^5.0.0",
"tape": "^4.9.2",
"tape-run": "^6.0.0",
"tape-run": "^5.0.0",
"uglify-es": "^3.3.7"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"homepage": "https://sequencer.publiclab.org",
"bin": {
"sequencer": "./index.js"

View File

@@ -1,42 +1,42 @@
describe('Default sequencer HTML', function() {
var DefaultHtmlSequencerUi = require('../examples/lib/defaultHtmlSequencerUi');
var sequencer = require('../src/ImageSequencer')();
var DefaultHtmlSequencerUi = require('../examples/lib/defaultHtmlSequencerUi')
var sequencer = require('../src/ImageSequencer')()
var defaultHtmlSequencerUi;
beforeEach(()=>{
defaultHtmlSequencerUi = new DefaultHtmlSequencerUi(sequencer);
defaultHtmlSequencerUi = new DefaultHtmlSequencerUi(sequencer)
spyOn(defaultHtmlSequencerUi, 'onLoad');
spyOn(defaultHtmlSequencerUi, 'selectNewStepUi');
spyOn(defaultHtmlSequencerUi, 'removeStepUi');
spyOn(defaultHtmlSequencerUi, 'addStepUi');
spyOn(defaultHtmlSequencerUi, 'importStepsFromUrlHash');
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();
});
defaultHtmlSequencerUi.onLoad()
defaultHtmlSequencerUi.selectNewStepUi()
defaultHtmlSequencerUi.addStepUi()
defaultHtmlSequencerUi.removeStepUi()
defaultHtmlSequencerUi.importStepsFromUrlHash()
})
it('load default ui', function() {
expect(defaultHtmlSequencerUi.onLoad).toHaveBeenCalled();
});
expect(defaultHtmlSequencerUi.onLoad).toHaveBeenCalled()
})
it('select step ui', function() {
expect(defaultHtmlSequencerUi.selectNewStepUi).toHaveBeenCalled();
});
expect(defaultHtmlSequencerUi.selectNewStepUi).toHaveBeenCalled()
})
it('add step ui', function() {
expect(defaultHtmlSequencerUi.addStepUi).toHaveBeenCalled();
});
expect(defaultHtmlSequencerUi.addStepUi).toHaveBeenCalled()
})
it('remove step ui', function() {
expect(defaultHtmlSequencerUi.removeStepUi).toHaveBeenCalled();
});
expect(defaultHtmlSequencerUi.removeStepUi).toHaveBeenCalled()
})
it('import options from url', function() {
expect(defaultHtmlSequencerUi.importStepsFromUrlHash).toHaveBeenCalled();
});
});
expect(defaultHtmlSequencerUi.importStepsFromUrlHash).toHaveBeenCalled()
})
})

View File

@@ -1,61 +1,61 @@
var { JSDOM } = require('jsdom');
var DOM = new JSDOM('<body></body>');
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 = require('../examples/lib/defaultHtmlStepUi')
var sequencer = require('../src/ImageSequencer')()
var defaultHtmlStepUi;
var step = 'brightness';
var step = 'brightness'
var options = {
name: 'Brightness',
description: 'Change the brightness of the image by given percent value'
};
name: "Brightness",
description: "Change the brightness of the image by given percent value"
}
// options = JSON.parse(options)
beforeEach(()=>{
defaultHtmlStepUi = new DefaultHtmlStepUi(sequencer);
defaultHtmlStepUi = new DefaultHtmlStepUi(sequencer)
spyOn(defaultHtmlStepUi, 'getPreview');
spyOn(defaultHtmlStepUi, 'onSetup');
spyOn(defaultHtmlStepUi, 'onComplete');
spyOn(defaultHtmlStepUi, 'onDraw');
spyOn(defaultHtmlStepUi, 'onRemove');
spyOn(defaultHtmlStepUi, 'notify');
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');
});
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();
});
expect(defaultHtmlStepUi.getPreview).toHaveBeenCalled()
})
it('load initial setup ui', function() {
expect(defaultHtmlStepUi.onSetup).toHaveBeenCalledWith(step, options);
});
expect(defaultHtmlStepUi.onSetup).toHaveBeenCalledWith(step,options)
})
it('load completion ui', function() {
expect(defaultHtmlStepUi.onComplete).toHaveBeenCalledWith(step);
});
expect(defaultHtmlStepUi.onComplete).toHaveBeenCalledWith(step)
})
it('draw step ui', function() {
expect(defaultHtmlStepUi.onDraw).toHaveBeenCalledWith(step);
});
expect(defaultHtmlStepUi.onDraw).toHaveBeenCalledWith(step)
})
it('remove step ui', function() {
expect(defaultHtmlStepUi.onRemove).toHaveBeenCalledWith(step);
});
expect(defaultHtmlStepUi.onRemove).toHaveBeenCalledWith(step)
})
it('notification ui', function() {
expect(defaultHtmlStepUi.notify).toHaveBeenCalledWith('Step removed', 'remove-notification');
});
expect(defaultHtmlStepUi.notify).toHaveBeenCalledWith('Step removed','remove-notification')
})
});
})

View File

@@ -1,26 +1,26 @@
describe('Preview UI HTML', function() {
var InsertPreview = require('../examples/lib/insertPreview');
var sequencer = require('../src/ImageSequencer')();
var InsertPreview = require('../examples/lib/insertPreview')
var sequencer = require('../src/ImageSequencer')()
var insertPreview;
var options = { brightness: 50 };
var options = { brightness: 50 }
beforeEach(()=>{
insertPreview = InsertPreview;
insertPreview = InsertPreview
spyOn(insertPreview, 'generatePreview');
spyOn(insertPreview, 'updatePreviews');
spyOn(insertPreview,'generatePreview')
spyOn(insertPreview,'updatePreviews')
insertPreview.generatePreview('brightness', options, 'src', 'selector');
insertPreview.updatePreviews('src', 'selector');
});
insertPreview.generatePreview('brightness',options,'src','selector')
insertPreview.updatePreviews('src','selector')
})
it('generate preview ui', function() {
expect(insertPreview.generatePreview).toHaveBeenCalledWith('brightness', options, 'src', 'selector');
});
expect(insertPreview.generatePreview).toHaveBeenCalledWith('brightness',options,'src','selector')
})
it('update preview ui', function() {
expect(insertPreview.updatePreviews).toHaveBeenCalledWith('src', 'selector');
});
expect(insertPreview.updatePreviews).toHaveBeenCalledWith('src','selector')
})
});
})

View File

@@ -1,19 +1,19 @@
describe('Intermediate step HTML', function() {
var IntermediateHtmlStepUi = require('../examples/lib/intermediateHtmlStepUi');
var sequencer = require('../src/ImageSequencer')();
var IntermediateHtmlStepUi = require('../examples/lib/intermediateHtmlStepUi')
var sequencer = require('../src/ImageSequencer')()
var intermediateHtmlStepUi;
beforeEach(()=>{
intermediateHtmlStepUi = new IntermediateHtmlStepUi(sequencer);
intermediateHtmlStepUi = new IntermediateHtmlStepUi(sequencer)
spyOn(intermediateHtmlStepUi, 'insertStep');
spyOn(intermediateHtmlStepUi,'insertStep')
intermediateHtmlStepUi.insertStep();
});
intermediateHtmlStepUi.insertStep()
})
it('insert step ui', function() {
expect(intermediateHtmlStepUi.insertStep).toHaveBeenCalled();
});
expect(intermediateHtmlStepUi.insertStep).toHaveBeenCalled()
})
});
})

View File

@@ -1,40 +1,40 @@
describe('URL manipulation methods', function() {
var UrlHash = require('../examples/lib/urlHash');
var UrlHash = require('../examples/lib/urlHash')
var urlHash;
var params = {
module: 'brightness',
brightness: 50
};
}
beforeEach(()=>{
urlHash = UrlHash;
urlHash = UrlHash
spyOn(urlHash, 'getUrlHashParameters');
spyOn(urlHash, 'getUrlHashParameter');
spyOn(urlHash, 'setUrlHashParameters');
spyOn(urlHash, 'setUrlHashParameter');
spyOn(urlHash,'getUrlHashParameters')
spyOn(urlHash,'getUrlHashParameter')
spyOn(urlHash,'setUrlHashParameters')
spyOn(urlHash,'setUrlHashParameter')
urlHash.getUrlHashParameters();
urlHash.getUrlHashParameter('module');
urlHash.setUrlHashParameters(params);
urlHash.setUrlHashParameter('module', 'brightness');
});
urlHash.getUrlHashParameters()
urlHash.getUrlHashParameter('module')
urlHash.setUrlHashParameters(params)
urlHash.setUrlHashParameter('module','brightness')
})
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() {
expect(urlHash.getUrlHashParameter).toHaveBeenCalledWith('module');
});
expect(urlHash.getUrlHashParameter).toHaveBeenCalledWith('module')
})
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() {
expect(urlHash.setUrlHashParameter).toHaveBeenCalledWith('module', 'brightness');
});
expect(urlHash.setUrlHashParameter).toHaveBeenCalledWith('module','brightness')
})
});
})

View File

@@ -1,5 +1,5 @@
// add steps to the sequencer
function AddStep(_sequencer, name, o) {
return require('./InsertStep')(_sequencer, -1, name, o);
return require('./InsertStep')(_sequencer,-1,name,o);
}
module.exports = AddStep;

View File

@@ -1,18 +1,18 @@
var fs = require('fs');
var fs = require('fs')
/*
* This function checks if the directory exists, if not it creates one on the given path
* Callback is called with argument error if an error is encountered
*/
function makedir(path, callback){
fs.access(path, function(err){
if(err) fs.mkdir(path, function(err){
if(err) callback(err);
callback();
function makedir(path,callback){
fs.access(path,function(err){
if(err) fs.mkdir(path,function(err){
if(err) callback(err);
callback();
});
else callback()
});
else callback();
});
}
};
// Takes an array of steps and checks if they are valid steps for the sequencer.
function validateSteps(steps, sequencer) {
@@ -37,9 +37,9 @@ function validateConfig(config_, options_) {
for (var input in options_) {
if (!config_[options_[input]]) {
console.error(
'\x1b[31m%s\x1b[0m',
"\x1b[31m%s\x1b[0m",
`Options Object does not have the required details "${
options_[input]
options_[input]
}" not specified. Fallback case activated`
);
return false;
@@ -52,7 +52,7 @@ function validateConfig(config_, options_) {
}
module.exports = exports = {
makedir: makedir,
validateSteps: validateSteps,
validateConfig: validateConfig
};
makedir: makedir,
validateSteps: validateSteps,
validateConfig: validateConfig
}

View File

@@ -2,7 +2,7 @@ var fs = require('fs');
var getDirectories = function(rootDir, cb) {
fs.readdir(rootDir, function(err, files) {
var dirs = [];
if (typeof (files) == 'undefined' || files.length == 0) {
if (typeof (files) == "undefined" || files.length == 0) {
cb(dirs);
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
dir = (dir[dir.length - 1] == '/') ? dir : dir + '/';
dir = (dir[dir.length - 1] == "/") ? dir : dir + "/";
if (ref.options.inBrowser) return false;
fs.access(dir, function(err) {
if (err) console.error(err);
if (err) console.error(err)
});
if (filename && basic) {
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 ext = steps.slice(-1)[0].output.format;
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 {
for (var i in steps) {
var datauri = steps[i].output.src;
var ext = steps[i].output.format;
var buffer = require('data-uri-to-buffer')(datauri);
fs.writeFile(root + 'image' + '_' + i + '.' + ext, buffer, function() { });
fs.writeFile(root + "image" + "_" + i + "." + ext, buffer, function() { });
}
}
});
});
}
};
}

View File

@@ -1,19 +1,19 @@
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){
return (objTypeOf(object) == 'Array') ? object[0] : object;
return (objTypeOf(object)=='Array')?object[0]:object;
}
function makeArray(input) {
return (objTypeOf(input) == 'Array') ? input : [input];
return (objTypeOf(input)=="Array")?input:[input];
}
function copy(a) {
if (!typeof(a) == 'object') return a;
if (objTypeOf(a) == 'Array') return a.slice();
if (objTypeOf(a) == 'Object') {
if (!typeof(a) == "object") return a;
if (objTypeOf(a) == "Array") return a.slice();
if (objTypeOf(a) == "Object") {
var b = {};
for (var v in a) {
b[v] = copy(a[v]);
@@ -23,80 +23,80 @@ function copy(a) {
return a;
}
function formatInput(args, format, images) {
function formatInput(args,format,images) {
var json_q = {};
var format_i = format;
if (format == '+')
if (format == "+")
format = ['string_a', 'o_object'];
else if (format == '-')
else if (format == "-")
format = ['number_a'];
else if (format == '^')
else if (format == "^")
format = ['number', 'string', 'o_object'];
else if (format == 'r')
else if (format == "r")
format = ['o_number'];
else if (format == 'l')
format = ['string', 'o_function'];
else if (format == "l")
format = ['string','o_function'];
if(format[format.length - 1] == 'o_object') {
if(objTypeOf(args[args.length - 1]) != 'Object')
if(format[format.length-1] == "o_object") {
if(objTypeOf(args[args.length-1]) != "Object")
args.push({});
}
else if (format[format.length - 1] == 'o_number') {
if(typeof(args[args.length - 1]) != 'number' && objTypeOf(args[0]) != 'Object')
else if (format[format.length-1] == "o_number") {
if(typeof(args[args.length-1]) != "number" && objTypeOf(args[0])!="Object")
args.push(1);
}
else if (format[format.length - 1] == 'o_function') {
if(objTypeOf(args[args.length - 1]) != 'Function' && objTypeOf(args[0]) != 'Object')
else if (format[format.length-1] == "o_function") {
if(objTypeOf(args[args.length-1]) != "Function" && objTypeOf(args[0])!="Object")
args.push(function(){});
}
if(args.length == format.length) {//making of arrays
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]);
}
}
if (args.length == 1 ) {
if(format_i == 'r') json_q = {0:copy(args[0])};
else if(format_i == '-') {
json_q = [];
json_q = copy(args[0]);
if(format_i == "r") json_q = {0:copy(args[0])};
else if(format_i == "-") {
json_q=[];
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]};
}
else if (format_i == 'l') {
else if (format_i == "l") {
json_q = {
image: args[0],
callback: args[1]
};
}
}
else {
json_q = [];
if(format_i == '+') {
for(var s in args[0]) {
json_q.push({
name: args[0][s],
o: args[1]
});
json_q = [];
if(format_i == "+") {
for(var s in args[0]) {
json_q.push({
name: args[0][s],
o: args[1]
});
}
}
}
if(format_i == '^') {
var size = this.steps.length;
var index = args[0];
index = (index == size) ? index : index % size;
if (index < 0) index += size + 1;
json_q.push({
index: index,
name: args[1],
o: args[2]
});
if(format_i == "^") {
var size = this.steps.length;
var index = args[0];
index = (index==size)?index:index%size;
if (index<0) index += size+1;
json_q.push({
index: index,
name: args[1],
o: args[2]
});
}
}

View File

@@ -1,29 +1,30 @@
if (typeof window !== 'undefined') { isBrowser = true; }
else { var isBrowser = false; }
if (typeof window !== 'undefined') { isBrowser = true }
else { var isBrowser = false }
require('./util/getStep.js');
ImageSequencer = function ImageSequencer(options) {
var sequencer = (this.name == 'ImageSequencer') ? this : this.sequencer;
var sequencer = (this.name == "ImageSequencer") ? this : this.sequencer;
options = options || {};
options.inBrowser = options.inBrowser === undefined ? isBrowser : options.inBrowser;
options.sequencerCounter = 0;
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) {
if (options.ui != 'none') {
if (options.ui != "none") {
if (arguments.length == 1) console.log(arguments[0]);
else if (arguments.length == 2) console.log(color, msg);
}
}
function copy(a) {
if (!typeof (a) == 'object') return a;
if (objTypeOf(a) == 'Array') return a.slice();
if (objTypeOf(a) == 'Object') {
var b = {};
if (!typeof (a) == "object") return a;
if (objTypeOf(a) == "Array") return a.slice();
if (objTypeOf(a) == "Object") {
var b = {};
for (var v in a) {
b[v] = copy(a[v]);
}
@@ -33,7 +34,7 @@ ImageSequencer = function ImageSequencer(options) {
}
function makeArray(input) {
return (objTypeOf(input) == 'Array') ? input : [input];
return (objTypeOf(input) == "Array") ? input : [input];
}
var image,
@@ -63,15 +64,15 @@ ImageSequencer = function ImageSequencer(options) {
// else if (options.imageUrl) loadImage(imageUrl);
function addSteps() {
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = [];
var json_q = {};
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) });
for (var j in json_q)
require('./AddStep')(this_, json_q[j].name, json_q[j].o);
inputlog.push({ method: "addSteps", json_q: copy(json_q) });
for (var j in json_q)
require("./AddStep")(this_, json_q[j].name, json_q[j].o);
return this;
}
@@ -88,31 +89,31 @@ ImageSequencer = function ImageSequencer(options) {
function removeSteps() {
var indices;
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = [];
for (var arg in arguments) args.push(copy(arguments[arg]));
var json_q = formatInput.call(this_, args, '-');
inputlog.push({ method: 'removeSteps', json_q: copy(json_q) });
var json_q = formatInput.call(this_, args, "-");
inputlog.push({ method: "removeSteps", json_q: copy(json_q) });
indices = json_q.sort(function(a, b) { return b - a; });
for (var i in indices)
removeStep(this_, indices[i]);
indices = json_q.sort(function(a, b) { return b - a });
for (var i in indices)
removeStep(this_, indices[i]);
return this;
}
function insertSteps() {
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
var args = [];
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = []
for (var arg in arguments) args.push(arguments[arg]);
var json_q = formatInput.call(this_, args, '^');
inputlog.push({ method: 'insertSteps', json_q: copy(json_q) });
var json_q = formatInput.call(this_, args, "^");
inputlog.push({ method: "insertSteps", json_q: copy(json_q) });
var details = json_q;
details = details.sort(function(a, b) { return b.index - a.index; });
for (var i in details)
require('./InsertStep')(this_, details[i].index, details[i].name, details[i].o);
var details = json_q;
details = details.sort(function(a, b) { return b.index - a.index });
for (var i in details)
require("./InsertStep")(this_, details[i].index, details[i].name, details[i].o);
return this;
}
@@ -123,21 +124,21 @@ ImageSequencer = function ImageSequencer(options) {
config = config || { mode: 'no-arg' };
if (config.index) index = config.index;
if (config.mode != 'no-arg' && typeof config != 'function') {
if (config.progressObj) progressObj = config.progressObj;
delete arguments['0'];
}
if (config.mode != "no-arg" && typeof config != 'function') {
if (config.progressObj) progressObj = config.progressObj;
delete arguments['0'];
}
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = [];
for (var arg in arguments) args.push(copy(arguments[arg]));
var callback = function() { };
for (var arg in args)
if (objTypeOf(args[arg]) == 'Function')
if (objTypeOf(args[arg]) == "Function")
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);
@@ -146,19 +147,19 @@ ImageSequencer = function ImageSequencer(options) {
function loadImages() {
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;
sequencer.image = arguments[0];
for (var arg in arguments) args.push(copy(arguments[arg]));
var json_q = formatInput.call(this, args, 'l');
if(this.getSteps().length != 0){
var json_q = formatInput.call(this, args, "l");
if(this.getSteps().length!=0){
this.options.sequencerCounter = 0;
inputlog = [];
this.steps = [];
}
inputlog.push({ method: 'loadImages', json_q: copy(json_q) });
inputlog.push({ method: "loadImages", json_q: copy(json_q) });
var ret = {
name: 'ImageSequencer Wrapper',
name: "ImageSequencer Wrapper",
sequencer: this,
addSteps: this.addSteps,
removeSteps: this.removeSteps,
@@ -168,16 +169,16 @@ ImageSequencer = function ImageSequencer(options) {
setUI: this.setUI
};
function loadPrevSteps(ref){
if(prevSteps.length != 0){
ref.addSteps(prevSteps);
prevSteps = [];
if(prevSteps.length!=0){
ref.addSteps(prevSteps)
prevSteps=[];
}
}
require('./ui/LoadImage')(sequencer, 'image', json_q.image, function() {
require('./ui/LoadImage')(sequencer, "image", json_q.image, function() {
loadPrevSteps(sequencer);
json_q.callback.call(ret);
});
}
function replaceImage(selector, steps, options) {
@@ -197,11 +198,11 @@ ImageSequencer = function ImageSequencer(options) {
var exportBin = function(dir, basic, filename) {
return require('./ExportBin')(dir, this, basic, filename);
};
}
function modulesInfo(name) {
var modulesdata = {};
if (name == 'load-image') return {};
var modulesdata = {}
if (name == "load-image") return {};
if (arguments.length == 0) {
for (var modulename in this.modules) {
modulesdata[modulename] = modules[modulename][1];
@@ -211,15 +212,133 @@ ImageSequencer = function ImageSequencer(options) {
}
}
else {
if (modules[name]){
modulesdata = modules[name][1];
}
if (modules[name]){
modulesdata = modules[name][1];
}
else
modulesdata = { 'inputs': sequences[name]['options'] };
}
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) {
if (!options) {
@@ -252,7 +371,7 @@ ImageSequencer = function ImageSequencer(options) {
return;
}
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);
}
@@ -282,11 +401,9 @@ ImageSequencer = function ImageSequencer(options) {
this.sequences = require('./SavedSequences.json');
}
var str = require('./Strings.js')(this.steps, modulesInfo, addSteps, copy);
return {
//literals and objects
name: 'ImageSequencer',
name: "ImageSequencer",
options: options,
inputlog: inputlog,
modules: modules,
@@ -306,17 +423,14 @@ ImageSequencer = function ImageSequencer(options) {
setUI: setUI,
exportBin: exportBin,
modulesInfo: modulesInfo,
toCliString: str.toCliString,
detectStringSyntax: str.detectStringSyntax,
parseStringSyntax: str.parseStringSyntax,
stringToSteps: str.stringToSteps,
toString: str.toString,
stepToString: str.stepToString,
toJSON: str.toJSON,
stringToJSON: str.stringToJSON,
stringToJSONstep: str.stringToJSONstep,
importString: str.importString,
importJSON: str.importJSON,
toCliString: toCliString,
toString: toString,
stepToString: stepToString,
toJSON: toJSON,
stringToJSON: stringToJSON,
stringToJSONstep: stringToJSONstep,
importString: importString,
importJSON: importJSON,
loadNewModule: loadNewModule,
saveNewModule: saveNewModule,
createMetaModule: require('./util/createMetaModule'),
@@ -330,7 +444,7 @@ ImageSequencer = function ImageSequencer(options) {
copy: copy,
setInputStep: require('./ui/SetInputStep')(sequencer)
};
}
};
}
module.exports = ImageSequencer;

View File

@@ -6,9 +6,6 @@ function InsertStep(ref, index, name, o) {
return ref.importJSON(ref.sequences[name]);
}
if (ref.detectStringSyntax(name)) {
return ref.stringToSteps(name);
}
function insertStep(index, name, o_) {
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.name = o_.name || name || moduleInfo.name;
o.description = o_.description || moduleInfo.description;
o.moduleInfo = o_.moduleInfo || moduleInfo;
o.selector = o_.selector || 'ismod-' + name;
o.container = o_.container || ref.options.selector;
o.inBrowser = ref.options.inBrowser;
o.useWasm = (ref.options.useWasm === false) ? false : true;
if (index == -1) index = ref.steps.length;
o.step = {
name: o.name,
description: o.description,
moduleInfo: o.moduleInfo,
ID: o.number,
inBrowser: ref.options.inBrowser,
ui: ref.options.ui,
@@ -45,7 +40,7 @@ function InsertStep(ref, index, name, o) {
let step = stepsArray[i];
ref.insertSteps(index + Number.parseInt(i), step['name'], step['options']);
}
};
}
// Tell UI that a step has been set up.
o = o || {};

View File

@@ -31,9 +31,8 @@ module.exports = {
'invert': require('image-sequencer-invert'),
'ndvi': require('./modules/Ndvi'),
'ndvi-colormap': require('./modules/NdviColormap'),
'noise-reduction': require('./modules/NoiseReduction'),
'overlay': require('./modules/Overlay'),
'paint-bucket': require('./modules/PaintBucket'),
'overlay': require('./modules/Overlay'),
'replace-color': require('./modules/ReplaceColor'),
'resize': require('./modules/Resize'),
'rotate': require('./modules/Rotate'),
@@ -41,6 +40,5 @@ module.exports = {
'text-overlay': require('./modules/TextOverlay'),
'threshold': require('./modules/Threshold'),
'tint': require('./modules/Tint'),
'webgl-distort': require('./modules/WebglDistort'),
'white-balance': require('./modules/WhiteBalance')
};
}

View File

@@ -1,6 +1,6 @@
// Uses a given image as input and replaces it with the output.
// Works only in the browser.
function ReplaceImage(ref, selector, steps, options) {
function ReplaceImage(ref,selector,steps,options) {
if(!ref.options.inBrowser) return false; // This isn't for Node.js
var tempSequencer = ImageSequencer({ui: false});
var this_ = ref;
@@ -26,27 +26,23 @@ function ReplaceImage(ref, selector, steps, options) {
// https://github.com/publiclab/image-sequencer/issues/241
// https://stackoverflow.com/a/20048852/1116657
var raw = '';
var i, j, subArray, chunk = 5000;
for (i = 0, j = arr.length; i < j; i += chunk) {
subArray = arr.subarray(i, i + chunk);
var i,j,subArray,chunk = 5000;
for (i=0,j=arr.length; i<j; i+=chunk) {
subArray = arr.subarray(i,i+chunk);
raw += String.fromCharCode.apply(null, subArray);
}
var base64 = btoa(raw);
var dataURL = 'data:image/' + ext + ';base64,' + base64;
var dataURL="data:image/"+ext+";base64," + base64;
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);
function make(url) {
tempSequencer.loadImage(url, function(){
// 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){
this.addSteps(steps).run({stop:function(){}},function(out){
img.src = out;
});
});
@@ -54,8 +50,8 @@ function ReplaceImage(ref, selector, steps, options) {
}
for (var i = 0; i < images.length; i++) {
replaceImage(images[i], steps);
if (i == images.length - 1)
replaceImage(images[i],steps);
if (i == images.length-1)
options.callback();
}
}

View File

@@ -5,7 +5,7 @@ function Run(ref, json_q, callback, ind, progressObj) {
function drawStep(drawarray, pos) {
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 out = steps[steps.length - 1].output.src;
callback(out);
@@ -25,7 +25,7 @@ function Run(ref, json_q, callback, ind, progressObj) {
};
step.getIndex = function getIndex() {
return i;
};
}
for (var util in getStepUtils) {
if (getStepUtils.hasOwnProperty(util)) {
@@ -43,7 +43,7 @@ function Run(ref, json_q, callback, ind, progressObj) {
inputForNextStep,
function onEachStep() {
// This output is accessible by UI
// This output is accessible by UI
ref.steps[i].options.step.output = ref.steps[i].output.src;
// Tell UI that step has been drawn.
@@ -58,26 +58,26 @@ function Run(ref, json_q, callback, ind, progressObj) {
function drawSteps(json_q) {
var drawarray = [],
no_steps = ref.steps.length,
init = json_q[0];
for (var i = 0; i < no_steps - init; i++) {
drawarray.push({i: init + i });
}
no_steps = ref.steps.length,
init = json_q[0];
for (var i = 0; i < no_steps - init; i++) {
drawarray.push({i: init + i });
}
drawStep(drawarray, ind);
}
function filter(json_q) {
if (json_q[0] == 0 && ref.steps.length == 1)
delete json_q[0];
else if (json_q[0] == 0) json_q[0]++;
var prevstep = ref.steps[json_q[0] - 1];
while (
typeof prevstep == 'undefined' ||
typeof prevstep.output == 'undefined'
) {
prevstep = ref.steps[--json_q[0] - 1];
}
if (json_q[0] == 0 && ref.steps.length == 1)
delete json_q[0];
else if (json_q[0] == 0) json_q[0]++;
var prevstep = ref.steps[json_q[0] - 1];
while (
typeof prevstep == "undefined" ||
typeof prevstep.output == "undefined"
) {
prevstep = ref.steps[--json_q[0] - 1];
}
return json_q;
}

View File

@@ -5,10 +5,10 @@ const dataUriToBuffer = require('data-uri-to-buffer');
const savePixels = require('save-pixels');
module.exports = function(input) {
input.getPixels = getPixels;
input.pixelManipulation = pixelManipulation;
input.lodash = lodash;
input.dataUriToBuffer = dataUriToBuffer;
input.savePixels = savePixels;
return input;
};
input.getPixels = getPixels;
input.pixelManipulation = pixelManipulation;
input.lodash = lodash;
input.dataUriToBuffer = dataUriToBuffer;
input.savePixels = savePixels;
return input;
}

View File

@@ -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
};
};

View File

@@ -1,17 +1,17 @@
var childProcess = require('child_process');
var childProcess = require('child_process')
var Spinner = require('ora');
module.exports = function (program, sequencer) {
console.log(
'\x1b[33m%s\x1b[0m',
'Please wait while your Module is being Installed...\nThis may take a while!'
);
console.log(
"\x1b[33m%s\x1b[0m",
"Please wait while your Module is being Installed...\nThis may take a while!"
);
var params = program.installModule.split(' ');
var spinner = Spinner('Now Installing...').start();
childProcess.execSync(`npm i ${params[1]}`);
sequencer.saveNewModule(params[0], params[1]);
sequencer.loadNewModule(params[0], require(params[1]));
spinner.stop();
console.log('\x1b[32m%s\x1b[0m', 'Your module was installed successfully!!');
};
var params = program.installModule.split(' ');
var spinner = Spinner("Now Installing...").start();
childProcess.execSync(`npm i ${params[1]}`)
sequencer.saveNewModule(params[0], params[1]);
sequencer.loadNewModule(params[0], require(params[1]));
spinner.stop();
console.log("\x1b[32m%s\x1b[0m", "Your module was installed successfully!!");
}

View File

@@ -1,7 +1,7 @@
module.exports = function (program, sequencer) {
var params = program.saveSequence.split(' ');
sequencer.saveSequence(params[0], params[1]);
console.log('\x1b[32m', 'Your sequence was saved successfully!!');
var params = program.saveSequence.split(' ');
sequencer.saveSequence(params[0], params[1]);
console.log("\x1b[32m", "Your sequence was saved successfully!!");
};
}

View File

@@ -1,13 +1,13 @@
var Spinner = require('ora');
var readlineSync = require('readline-sync');
var utils = require('../CliUtils');
var utils = require('../CliUtils')
module.exports = function (program, sequencer, outputFilename) {
utils.makedir(program.output, () => {
console.log('Files will be exported to "' + program.output + '"');
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.
program.step.forEach(function(step) {
@@ -15,7 +15,7 @@ module.exports = function (program, sequencer, outputFilename) {
// If inputs exists, print to console.
if (Object.keys(options).length) {
console.log('[' + step + ']: Inputs');
console.log("[" + step + "]: Inputs");
}
// 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 extra 4 that makes it (length + 5) is to account for the []: characters
console.log(
new Array(step.length + 5).join(' ') +
new Array(step.length + 5).join(" ") +
input +
': ' +
": " +
options[input].desc
);
});
@@ -33,18 +33,18 @@ module.exports = function (program, sequencer, outputFilename) {
if (program.config) {
try {
var config = JSON.parse(program.config);
console.log('The parsed options object: ', config);
console.log(`The parsed options object: `, config);
} catch (e) {
console.error(
'\x1b[31m%s\x1b[0m',
'Options(Config) is not a not valid JSON Fallback activate'
"\x1b[31m%s\x1b[0m",
`Options(Config) is not a not valid JSON Fallback activate`
);
program.config = false;
console.log(e);
}
}
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) {
options[input] = config[input];
});
@@ -52,15 +52,15 @@ module.exports = function (program, sequencer, outputFilename) {
// If inputs exist, iterate through them and prompt for values.
Object.keys(options).forEach(function(input) {
var value = readlineSync.question(
'[' +
"[" +
step +
']: Enter a value for ' +
"]: Enter a value for " +
input +
' (' +
" (" +
options[input].type +
', default: ' +
", default: " +
options[input].default +
'): '
"): "
);
options[input] = value;
});
@@ -71,7 +71,7 @@ module.exports = function (program, sequencer, outputFilename) {
var spinnerObj = { succeed: () => { }, stop: () => { } };
if (!process.env.TEST)
spinnerObj = Spinner('Your Image is being processed..').start();
spinnerObj = Spinner("Your Image is being processed..").start();
// Run the sequencer.
sequencer.run({ progressObj: spinnerObj }, function() {
@@ -81,8 +81,8 @@ module.exports = function (program, sequencer, outputFilename) {
//check if spinner was not overriden stop it
if (!spinnerObj.overrideFlag) {
spinnerObj.succeed();
console.log('\nDone!!');
console.log(`\nDone!!`);
}
});
});
};
}

View File

@@ -1,52 +1,51 @@
module.exports = function AddQR(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.size = options.size || defaults.size;
options.qrCodeString = options.qrCodeString || 'https://github.com/publiclab/image-sequencer';
var output;
getPixels = require('get-pixels');
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.size = options.size || defaults.size;
options.qrCodeString = options.qrCodeString || "https://github.com/publiclab/image-sequencer";
var output;
getPixels = require('get-pixels');
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
return getPixels(input.src, function(err, oldPixels) {
function changePixel(r, g, b, a) {
return [r, g, b, a];
}
return getPixels(input.src, function (err, oldPixels) {
function changePixel(r, g, b, a) {
return [r, g, b, a];
}
function extraManipulation(pixels,generateOutput) {
if (err) {
console.log(err);
return;
}
require('./QR')(options, pixels, oldPixels, generateOutput);
}
function output(image, datauri, mimetype) {
step.output = { src: datauri, format: mimetype };
}
function extraManipulation(pixels, generateOutput) {
if (err) {
console.log(err);
return;
}
require('./QR')(options, pixels, oldPixels, generateOutput);
}
function output(image, datauri, mimetype) {
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
})
}
return {
options: options,
draw: draw,
output: output,
ui: options.step.ui,
changePixel: changePixel,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
UI: UI
}
}

View File

@@ -1,48 +1,48 @@
module.exports = exports = function (options, pixels, oldPixels, callback) {
var QRCode = require('qrcode');
QRCode.toDataURL(options.qrCodeString, function (err, url) {
var getPixels = require('get-pixels');
getPixels(url, function (err, qrPixels) {
if (err) {
console.log('Bad image path', image);
}
var QRCode = require('qrcode')
QRCode.toDataURL(options.qrCodeString, function (err, url) {
var getPixels = require("get-pixels");
getPixels(url, function (err, qrPixels) {
if (err) {
console.log("Bad image path", image);
}
var imagejs = require('imagejs');
var bitmap = new imagejs.Bitmap({ width: qrPixels.shape[0], height: qrPixels.shape[1] });
bitmap._data.data = qrPixels.data;
var resized = bitmap.resize({
width: options.size, height: options.size,
algorithm: 'bicubicInterpolation'
});
var imagejs = require('imagejs');
var bitmap = new imagejs.Bitmap({ width: qrPixels.shape[0], height: qrPixels.shape[1] });
bitmap._data.data = qrPixels.data;
var resized = bitmap.resize({
width: options.size, height: options.size,
algorithm: "bicubicInterpolation"
});
qrPixels.data = resized._data.data;
qrPixels.shape = [options.size, options.size, 4];
qrPixels.stride[1] = 4 * options.size;
qrPixels.data = resized._data.data;
qrPixels.shape = [options.size, options.size, 4];
qrPixels.stride[1] = 4 * options.size;
var width = oldPixels.shape[0],
height = oldPixels.shape[1];
var xe = width - options.size,
ye = height - options.size;
for (var m = 0; m < width; m++) {
for (var n = 0; n < height; n++) {
if (m >= xe && n >= ye) {
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, 2, qrPixels.get(m - xe, n - ye, 2));
pixels.set(m, n, 3, qrPixels.get(m - xe, n - ye, 3));
}
var width = oldPixels.shape[0],
height = oldPixels.shape[1];
var xe = width - options.size,
ye = height - options.size;
for (var m = 0; m < width; m++) {
for (var n = 0; n < height; n++) {
if (m >= xe && n >= ye) {
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, 2, qrPixels.get(m - xe, n - ye, 2))
pixels.set(m, n, 3, qrPixels.get(m - xe, n - ye, 3))
}
else {
pixels.set(m, n, 0, oldPixels.get(m, n, 0));
pixels.set(m, n, 1, oldPixels.get(m, n, 1));
pixels.set(m, n, 2, oldPixels.get(m, n, 2));
pixels.set(m, n, 3, oldPixels.get(m, n, 3));
}
else {
pixels.set(m, n, 0, oldPixels.get(m, n, 0))
pixels.set(m, n, 1, oldPixels.get(m, n, 1))
pixels.set(m, n, 2, oldPixels.get(m, n, 2))
pixels.set(m, n, 3, oldPixels.get(m, n, 3))
}
}
}
callback();
}
}
callback();
});
});
};
})
})
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "add-qr",
"name": "Add QR",
"description": "Adds QR corresponding to the given string",
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
"inputs": {

View File

@@ -3,74 +3,72 @@
*/
module.exports = function Average(options, UI) {
var output;
var output;
options.step.metadata = options.step.metadata || {};
options.step.metadata = options.step.metadata || {};
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
// do the averaging
function extraManipulation(pixels) {
var i = 0, sum = [0, 0, 0, 0];
while (i < pixels.data.length) {
sum[0] += pixels.data[i++];
sum[1] += pixels.data[i++];
sum[2] += pixels.data[i++];
sum[3] += pixels.data[i++];
}
// do the averaging
function extraManipulation(pixels) {
var i = 0, sum = [0, 0, 0, 0];
while (i < pixels.data.length) {
sum[0] += pixels.data[i++];
sum[1] += pixels.data[i++];
sum[2] += pixels.data[i++];
sum[3] += pixels.data[i++];
}
let divisor = pixels.data.length / 4;
let divisor = pixels.data.length / 4;
sum[0] = Math.floor(sum[0] / divisor);
sum[1] = Math.floor(sum[1] / divisor);
sum[2] = Math.floor(sum[2] / divisor);
sum[3] = Math.floor(sum[3] / divisor);
sum[0] = Math.floor(sum[0] / divisor);
sum[1] = Math.floor(sum[1] / divisor);
sum[2] = Math.floor(sum[2] / divisor);
sum[3] = Math.floor(sum[3] / divisor);
i = 0;
while (i < pixels.data.length) {
pixels.data[i++] = sum[0];
pixels.data[i++] = sum[1];
pixels.data[i++] = sum[2];
pixels.data[i++] = sum[3];
}
i = 0
while (i < pixels.data.length) {
pixels.data[i++] = sum[0];
pixels.data[i++] = sum[1];
pixels.data[i++] = sum[2];
pixels.data[i++] = sum[3];
}
// report back and store average in metadata:
options.step.metadata.averages = sum;
// report back and store average in metadata:
options.step.metadata.averages = sum;
// 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>");
return pixels;
}
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = {
src: datauri,
format: mimetype
};
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback
});
// 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>');
return pixels;
}
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = {
src: datauri,
format: mimetype
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "average",
"name": "Average",
"description": "Average all pixel color",
"inputs": {
},

View File

@@ -1,77 +1,75 @@
module.exports = function Dynamic(options, UI, util) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.func = options.func || defaults.blend;
options.offset = options.offset || defaults.offset;
options.func = options.func || defaults.blend;
options.offset = options.offset || defaults.offset;
var output;
var output;
// This function is called on every draw.
function draw(input, callback, progressObj) {
// This function is called on every draw.
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
// convert to runnable code:
if (typeof options.func === 'string') eval('options.func = ' + options.func);
// convert to runnable code:
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
if (typeof options.offset === 'string') options.offset = parseInt(options.offset);
// convert offset as string to int
if (typeof options.offset === "string") options.offset = parseInt(options.offset);
// save first image's pixels
var priorStep = this.getStep(options.offset);
// save first image's pixels
var priorStep = this.getStep(options.offset);
if (priorStep.output === undefined) {
this.output = input;
UI.notify('Offset Unavailable', 'offset-notification');
callback();
if (priorStep.output === undefined) {
this.output = input;
UI.notify('Offset Unavailable', 'offset-notification');
callback();
}
getPixels(priorStep.output.src, function(err, pixels) {
options.firstImagePixels = pixels;
function changePixel(r2, g2, b2, a2, x, y) {
// blend!
let p = options.firstImagePixels;
return options.func(
r2, g2, b2, a2,
p.get(x, y, 0),
p.get(x, y, 1),
p.get(x, y, 2),
p.get(x, y, 3)
)
}
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
// run PixelManipulatin on second image's pixels
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
});
}
getPixels(priorStep.output.src, function(err, pixels) {
options.firstImagePixels = pixels;
function changePixel(r2, g2, b2, a2, x, y) {
// blend!
let p = options.firstImagePixels;
return options.func(
r2, g2, b2, a2,
p.get(x, y, 0),
p.get(x, y, 1),
p.get(x, y, 2),
p.get(x, y, 3)
);
}
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
// run PixelManipulatin on second image's pixels
return require('../_nomodule/PixelManipulation.js')(input, {
return {
options: options,
draw: draw,
output: output,
ui: options.step.ui,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -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!",
"inputs": {
"offset": {

View File

@@ -1,62 +1,84 @@
module.exports = exports = function(pixels, blur) {
let kernel = kernelGenerator(blur),
pixs = {
r: [],
g: [],
b: [],
};
let kernel = kernelGenerator(blur, 1), oldpix = require('lodash').cloneDeep(pixels);
kernel = flipKernel(kernel);
for (let y = 0; y < pixels.shape[1]; y++){
pixs.r.push([]);
pixs.g.push([]);
pixs.b.push([]);
for (let x = 0; x < pixels.shape[0]; x++){
pixs.r[y].push(pixels.get(x, y, 0));
pixs.g[y].push(pixels.get(x, y, 1));
pixs.b[y].push(pixels.get(x, y, 2));
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
let neighboutPos = getNeighbouringPixelPositions([i, j]);
let acc = [0.0, 0.0, 0.0, 0.0];
for (let a = 0; a < kernel.length; a++) {
for (let b = 0; b < kernel.length; b++) {
acc[0] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 0) * kernel[a][b]);
acc[1] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 1) * kernel[a][b]);
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]);
pixels.set(i, j, 1, acc[1]);
pixels.set(i, j, 2, acc[2]);
}
}
}
return pixels;
const convolve = require('../_nomodule/gpuUtils').convolve;
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)));
//Generates a 3x3 Gaussian kernel
function kernelGenerator(sigma, size) {
/*
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)))
// return result
return [
[2.0 / 159.0, 4.0 / 159.0, 5.0 / 159.0, 4.0 / 159.0, 2.0 / 159.0],
[4.0 / 159.0, 9.0 / 159.0, 12.0 / 159.0, 9.0 / 159.0, 4.0 / 159.0],
[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 = [];
return pixels;
for (let i = -2; i <= 2; i++) {
let arr = [];
for (let j = -2; j <= 2; j++)
arr.push([x + i, y + j]);
//Generates a 5x5 Gaussian kernel
function kernelGenerator(sigma = 1) {
let kernel = [],
sum = 0;
if (sigma == 0) sigma += 0.05;
const s = 2 * Math.pow(sigma, 2);
for (let y = -2; y <= 2; y++) {
kernel.push([]);
for (let x = -2; x <= 2; x++) {
let r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
kernel[y + 2].push(Math.exp(-(r / s)));
sum += kernel[y + 2][x + 2];
}
result.push(arr);
}
return result;
}
for (let x = 0; x < 5; x++){
for (let y = 0; y < 5; y++){
kernel[y][x] = (kernel[y][x] / sum);
}
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;
}
return kernel;
}
};
}

View File

@@ -3,45 +3,42 @@
*/
module.exports = function Blur(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.blur = options.blur || defaults.blur;
options.blur = parseFloat(options.blur);
var output;
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.blur = options.blur || defaults.blur;
var output;
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
function extraManipulation(pixels) {
pixels = require('./Blur')(pixels, options.blur);
return pixels;
}
function extraManipulation(pixels) {
pixels = require('./Blur')(pixels, options.blur);
return pixels;
}
function output(image, datauri, mimetype) {
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback
});
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "blur",
"name": "Blur",
"description": "Applies a Gaussian blur given by the intensity value",
"inputs": {
"blur": {
@@ -8,7 +8,7 @@
"default": 2,
"min": 0,
"max": 5,
"step": 0.05
"step": 0.25
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blur-module"

View File

@@ -3,57 +3,55 @@
*/
module.exports = function Brightness(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
options.brightness = options.brightness || defaults.brightness;
options.brightness = options.brightness || defaults.brightness;
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
/*
/*
In this case progress is handled by changepixel internally otherwise progressObj
needs to be overriden and used
For eg. progressObj = new SomeProgressModule()
*/
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) {
r = Math.min(val * r, 255);
g = Math.min(val * g, 255);
b = Math.min(val * b, 255);
return [r, g, b, a];
}
r = Math.min(val * r, 255);
g = Math.min(val * g, 255);
b = Math.min(val * b, 255);
return [r, g, b, a];
}
function output(image, datauri, mimetype) {
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui, //don't pass this in if you don't want your module to support progress bars
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "brightness",
"name": "Brightness",
"description": "Change the brightness of the image by given percent value",
"inputs": {
"brightness": {

View File

@@ -3,62 +3,61 @@
*/
module.exports = function canvasResize(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
options.width = parseInt(options.width || defaults.width);
options.height = parseInt(options.height || defaults.height);
options.x = parseInt(options.x || defaults.x);
options.y = parseInt(options.y || defaults.y);
options.width = options.width || defaults.width;
options.height = options.height || defaults.height;
options.x = options.x || defaults.x;
options.y = options.y || defaults.y;
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
function extraManipulation(pixels) {
let newPixels = require('ndarray')(new Uint8Array(4 * options.width * options.height).fill(0), [options.width, options.height, 4]);
let iMax = options.width - options.x,
jMax = options.height - options.y;
for (let i = 0; i < iMax && i < pixels.shape[0]; i++) {
for (let j = 0; j < jMax && j < pixels.shape[1]; j++) {
let x = i + options.x, y = j + options.y;
newPixels.set(x, y, 0, pixels.get(i, j, 0));
newPixels.set(x, y, 1, pixels.get(i, j, 1));
newPixels.set(x, y, 2, pixels.get(i, j, 2));
newPixels.set(x, y, 3, pixels.get(i, j, 3));
function extraManipulation(pixels) {
let newPixels = require('ndarray')(new Uint8Array(4 * options.width * options.height).fill(255), [options.width, options.height, 4]);
let iMax = options.width - options.x,
jMax = options.height - options.y;
for (let i = 0; i < iMax && i < pixels.shape[0]; i++) {
for (let j = 0; j < jMax && j < pixels.shape[1]; j++) {
let x = i + options.x, y = j + options.y;
newPixels.set(x, y, 0, pixels.get(i, j, 0));
newPixels.set(x, y, 1, pixels.get(i, j, 1));
newPixels.set(x, y, 2, pixels.get(i, j, 2));
newPixels.set(x, y, 3, pixels.get(i, j, 3));
}
}
return newPixels;
}
}
return newPixels;
}
function output(image, datauri, mimetype) {
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
// This output is accessible by Image Sequencer
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 require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -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",
"inputs": {
"width": {

View File

@@ -17,9 +17,9 @@ module.exports = function Channel(options, UI) {
var step = this;
function changePixel(r, g, b, a) {
if (options.channel === 'red') return [r, 0, 0, a];
if (options.channel === 'green') return [0, g, 0, a];
if (options.channel === 'blue') return [0, 0, b, a];
if (options.channel === "red") return [r, 0, 0, a];
if (options.channel === "green") return [0, g, 0, a];
if (options.channel === "blue") return [0, 0, b, a];
}
function output(image, datauri, mimetype) {
@@ -31,13 +31,11 @@ module.exports = function Channel(options, UI) {
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
callback: callback
});
}
@@ -48,5 +46,5 @@ module.exports = function Channel(options, UI) {
draw: draw,
output: output,
UI: UI
};
};
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "channel",
"name": "Channel",
"description": "Displays only one color channel of an image -- default is green",
"inputs": {
"channel": {

View File

@@ -1,83 +1,81 @@
module.exports = function ColorTemperature(options, UI) {
var output;
var output;
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.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
function extraManipulation(pixels) {
function extraManipulation(pixels) {
let temp = parseInt(options.temperature);
temp /= 100;
let temp = parseInt(options.temperature)
temp /= 100
let r, g, b;
let r, g, b;
if (temp <= 66) {
r = 255;
g = Math.min(Math.max(99.4708025861 * Math.log(temp) - 161.1195681661, 0), 255);
} else {
r = Math.min(Math.max(329.698727446 * Math.pow(temp - 60, -0.1332047592), 0), 255);
g = Math.min(Math.max(288.1221695283 * Math.pow(temp - 60, -0.0755148492), 0), 255);
}
if (temp <= 66) {
r = 255;
g = Math.min(Math.max(99.4708025861 * Math.log(temp) - 161.1195681661, 0), 255);
} else {
r = Math.min(Math.max(329.698727446 * Math.pow(temp - 60, -0.1332047592), 0), 255);
g = Math.min(Math.max(288.1221695283 * Math.pow(temp - 60, -0.0755148492), 0), 255);
}
if (temp >= 66) {
b = 255;
} else if (temp <= 19) {
b = 0;
} else {
b = temp - 10;
b = Math.min(Math.max(138.5177312231 * Math.log(b) - 305.0447927307, 0), 255);
}
if (temp >= 66) {
b = 255;
} else if (temp <= 19) {
b = 0;
} else {
b = temp - 10;
b = Math.min(Math.max(138.5177312231 * Math.log(b) - 305.0447927307, 0), 255);
}
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
r_data = pixels.get(i, j, 0);
r_new_data = (255 / r) * r_data;
pixels.set(i, j, 0, r_new_data);
r_data = pixels.get(i, j, 0)
r_new_data = (255 / r) * r_data
pixels.set(i, j, 0, r_new_data)
g_data = pixels.get(i, j, 1);
g_new_data = (255 / g) * g_data;
pixels.set(i, j, 1, g_new_data);
g_data = pixels.get(i, j, 1)
g_new_data = (255 / g) * g_data
pixels.set(i, j, 1, g_new_data)
b_data = pixels.get(i, j, 2);
b_new_data = (255 / b) * b_data;
pixels.set(i, j, 2, b_new_data);
b_data = pixels.get(i, j, 2)
b_new_data = (255 / b) * b_data
pixels.set(i, j, 2, b_new_data)
}
}
return pixels
}
}
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
});
}
function output(image, datauri, mimetype) {
step.output = { src: datauri, format: mimetype };
return {
options: options,
draw: draw,
output: output,
UI: UI
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "color-temperature",
"name": "Color Temperature",
"description": "Changes the color temperature of the image.",
"inputs": {
"temperature": {

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "colorbar",
"name": "Colorbar",
"description": "Generates a colorbar to lay over the image",
"inputs": {
"colormap": {

View File

@@ -1,27 +1,27 @@
/*
* Accepts a value from 0-255 and returns the new color-mapped pixel
* from a lookup table, which can be specified as an array of [begin, end]
* gradients, where begin and end are represented as [r, g, b] colors. In
* Accepts a value from 0-255 and returns the new color-mapped pixel
* from a lookup table, which can be specified as an array of [begin, end]
* gradients, where begin and end are represented as [r, g, b] colors. In
* combination, a lookup table which maps values from 0 - 255 smoothly from black to white looks like:
* [
* [0, [0, 0, 0], [255, 255, 255]],
* [1, [255, 255, 255], [255, 255, 255]]
* ]
*
*
* Adapted from bgamari's work in Infragram: https://github.com/p-v-o-s/infragram-js/commit/346c97576a07b71a55671d17e0153b7df74e803b
*/
module.exports = function Colormap(value, options) {
options.colormap = options.colormap || colormaps.default;
// if a lookup table is provided as an array:
if(typeof(options.colormap) == 'object')
if(typeof(options.colormap) == "object")
colormapFunction = colormap(options.colormap);
// if a stored colormap is named with a string like "fastie":
else if(colormaps.hasOwnProperty(options.colormap))
colormapFunction = colormaps[options.colormap];
else colormapFunction = colormaps.default;
return colormapFunction(value / 255.00);
};
}
function colormap(segments) {
return function(x) {
@@ -49,149 +49,149 @@ function colormap(segments) {
}
return result;
};
}
};
var colormaps = {
greyscale: colormap([
[0, [0, 0, 0], [255, 255, 255] ],
[1, [255, 255, 255], [255, 255, 255] ]
]),
[0, [0, 0, 0], [255, 255, 255] ],
[1, [255, 255, 255], [255, 255, 255] ]
]),
bluwhtgrngis: colormap([
[0, [6, 23, 86], [6, 25, 84] ],
[0.0625, [6, 25, 84], [6, 25, 84] ], //1
[0.125, [6, 25, 84], [6, 25, 84] ], //2
[0.1875, [6, 25, 84], [6, 25, 84] ],
[0.25, [6, 25, 84], [6, 25, 84] ],
[0.3125, [6, 25, 84], [9, 24, 84] ], //5
[0.3438, [9, 24, 84], [119, 120, 162] ], //5
[0.375, [119, 129, 162], [249, 250, 251] ], //6
[0.406, [249, 250, 251], [255, 255, 255] ], //6.5
[0.4375, [255, 255, 255], [255, 255, 255] ], //7 white
[0.50, [255, 255, 255], [214, 205, 191] ], //8
[0.52, [214, 205, 191], [178, 175, 96] ], //8.2
[0.5625, [178, 175, 96], [151, 176, 53] ], //9
[0.593, [151, 176, 53], [146, 188, 12] ], //9.5
[0.625, [146, 188, 12], [96, 161, 1] ], //10
[0.6875, [96, 161, 1], [30, 127, 3] ], //11
[0.75, [30, 127, 3], [0, 99, 1] ], //12
[0.8125, [0, 99, 1], [0, 74, 1] ], //13
[0.875, [0, 74, 1], [0, 52, 0] ], //14
[0.9375, [0, 52, 0], [0, 34, 0] ], //15
[0.968, [0, 34, 0], [68, 70, 67] ] //16
]),
bluwhtgrngis: colormap([
[0, [6,23,86], [6,25, 84] ],
[0.0625, [6,25,84], [6,25, 84] ],//1
[0.125, [6,25,84], [6,25, 84] ],//2
[0.1875, [6,25,84], [6,25, 84] ],
[0.25, [6,25,84], [6,25,84] ],
[0.3125, [6,25,84], [9,24, 84] ],//5
[0.3438, [9,24, 84], [119,120,162] ],//5
[0.375, [119,129,162],[249,250,251] ], //6
[0.406, [249,250,251],[255,255,255] ], //6.5
[0.4375, [255,255,255],[255,255,255] ], //7 white
[0.50, [255,255,255],[214,205,191] ],//8
[0.52, [214,205,191],[178,175,96] ],//8.2
[0.5625, [178,175,96], [151,176,53] ],//9
[0.593, [151,176,53], [146,188,12] ],//9.5
[0.625, [146,188,12], [96,161,1] ], //10
[0.6875, [96,161,1], [30,127,3] ],//11
[0.75, [30,127,3], [0,99,1] ],//12
[0.8125, [0,99,1], [0,74,1] ],//13
[0.875, [0,74,1], [0,52, 0] ],//14
[0.9375, [0,52, 0], [0,34,0] ], //15
[0.968, [0,34,0], [68,70,67] ] //16
]),
brntogrn: colormap([
[0, [110, 12, 3], [118, 6, 1] ],
[0.0625, [118, 6, 1], [141, 19, 6] ],
[0.125, [141, 19, 6], [165, 35, 13] ],
[0.1875, [165, 35, 13], [177, 59, 25] ],
[0.2188, [177, 59, 25], [192, 91, 36] ],
[0.25, [192, 91, 36], [214, 145, 76] ],
[0.3125, [214, 145, 76], [230, 183, 134] ],
[0.375, [230, 183, 134], [243, 224, 194]],
[0.4375, [243, 224, 194], [250, 252, 229] ],
[0.50, [250, 252, 229], [217, 235, 185] ],
[0.5625, [217, 235, 185], [184, 218, 143] ],
[0.625, [184, 218, 143], [141, 202, 89] ],
[0.6875, [141, 202, 89], [80, 176, 61] ],
[0.75, [80, 176, 61], [0, 147, 32] ],
[0.8125, [0, 147, 32], [1, 122, 22] ],
[0.875, [1, 122, 22], [0, 114, 19] ],
[0.90, [0, 114, 19], [0, 105, 18] ],
[0.9375, [0, 105, 18], [7, 70, 14] ]
[0, [110,12,3], [118,6,1] ],
[0.0625, [118,6,1], [141,19,6] ],
[0.125, [141,19,6], [165,35,13] ],
[0.1875, [165,35,13], [177,59,25] ],
[0.2188, [177,59,25], [192,91,36] ],
[0.25, [192,91,36], [214, 145, 76] ],
[0.3125, [214,145,76], [230,183,134] ],
[0.375, [230,183,134],[243, 224, 194]],
[0.4375, [243,224,194],[250,252,229] ],
[0.50, [250,252,229],[217,235,185] ],
[0.5625, [217,235,185],[184,218,143] ],
[0.625, [184,218,143],[141,202,89] ],
[0.6875, [141,202,89], [80,176,61] ],
[0.75, [80,176,61], [0, 147, 32] ],
[0.8125, [0,147,32], [1, 122, 22] ],
[0.875, [1,122,22], [0, 114, 19] ],
[0.90, [0,114,19], [0,105,18] ],
[0.9375, [0,105,18], [7,70,14] ]
]),
]),
blutoredjet: colormap([
[0, [0, 0, 140], [1, 1, 186] ],
[0.0625, [1, 1, 186], [0, 1, 248] ],
[0.125, [0, 1, 248], [0, 70, 254] ],
[0.1875, [0, 70, 254], [0, 130, 255] ],
[0.25, [0, 130, 255], [2, 160, 255] ],
[0.2813, [2, 160, 255], [0, 187, 255] ], //inset
[0.3125, [0, 187, 255], [6, 250, 255] ],
// [0.348, [0,218,255], [8,252,251] ],//inset
[0.375, [8, 252, 251], [27, 254, 228] ],
[0.406, [27, 254, 228], [70, 255, 187] ], //insert
[0.4375, [70, 255, 187], [104, 254, 151]],
[0.47, [104, 254, 151], [132, 255, 19] ], //insert
[0.50, [132, 255, 19], [195, 255, 60] ],
[0.5625, [195, 255, 60], [231, 254, 25] ],
[0.5976, [231, 254, 25], [253, 246, 1] ], //insert
[0.625, [253, 246, 1], [252, 210, 1] ], //yellow
[0.657, [252, 210, 1], [255, 183, 0] ], //insert
[0.6875, [255, 183, 0], [255, 125, 2] ],
[0.75, [255, 125, 2], [255, 65, 1] ],
[0.8125, [255, 65, 1], [247, 1, 1] ],
[0.875, [247, 1, 1], [200, 1, 3] ],
[0.9375, [200, 1, 3], [122, 3, 2] ]
[0, [0,0,140], [1,1,186] ],
[0.0625, [1,1,186], [0,1,248] ],
[0.125, [0,1,248], [0,70,254] ],
[0.1875, [0,70,254], [0,130,255] ],
[0.25, [0,130,255], [2,160,255] ],
[0.2813, [2,160,255], [0,187,255] ], //inset
[0.3125, [0,187,255], [6,250,255] ],
// [0.348, [0,218,255], [8,252,251] ],//inset
[0.375, [8,252,251], [27,254,228] ],
[0.406, [27,254,228], [70,255,187] ], //insert
[0.4375, [70,255,187], [104,254,151]],
[0.47, [104,254,151],[132,255,19] ],//insert
[0.50, [132,255,19], [195,255,60] ],
[0.5625, [195,255,60], [231,254,25] ],
[0.5976, [231,254,25], [253,246,1] ],//insert
[0.625, [253,246,1], [252,210,1] ], //yellow
[0.657, [252,210,1], [255,183,0] ],//insert
[0.6875, [255,183,0], [255,125,2] ],
[0.75, [255,125,2], [255,65, 1] ],
[0.8125, [255,65, 1], [247, 1, 1] ],
[0.875, [247,1,1], [200, 1, 3] ],
[0.9375, [200,1,3], [122, 3, 2] ]
]),
]),
colors16: colormap([
[0, [0, 0, 0], [0, 0, 0] ],
[0.0625, [3, 1, 172], [3, 1, 172] ],
[0.125, [3, 1, 222], [3, 1, 222] ],
[0.1875, [0, 111, 255], [0, 111, 255] ],
[0.25, [3, 172, 255], [3, 172, 255] ],
[0.3125, [1, 226, 255], [1, 226, 255] ],
[0.375, [2, 255, 0], [2, 255, 0] ],
[0.4375, [198, 254, 0], [190, 254, 0] ],
[0.50, [252, 255, 0], [252, 255, 0] ],
[0.5625, [255, 223, 3], [255, 223, 3] ],
[0.625, [255, 143, 3], [255, 143, 3] ],
[0.6875, [255, 95, 3], [255, 95, 3] ],
[0.75, [242, 0, 1], [242, 0, 1] ],
[0.8125, [245, 0, 170], [245, 0, 170] ],
[0.875, [223, 180, 225], [223, 180, 225] ],
[0.9375, [255, 255, 255], [255, 255, 255]]
[0, [0,0,0], [0,0,0] ],
[0.0625, [3,1,172], [3,1,172] ],
[0.125, [3,1,222], [3,1, 222] ],
[0.1875, [0,111,255], [0,111,255] ],
[0.25, [3,172,255], [3,172,255] ],
[0.3125, [1,226,255], [1,226,255] ],
[0.375, [2,255,0], [2,255,0] ],
[0.4375, [198,254,0], [190,254,0] ],
[0.50, [252,255,0], [252,255,0] ],
[0.5625, [255,223,3], [255,223,3] ],
[0.625, [255,143,3], [255,143,3] ],
[0.6875, [255,95,3], [255,95,3] ],
[0.75, [242,0,1], [242,0,1] ],
[0.8125, [245,0,170], [245,0,170] ],
[0.875, [223,180,225], [223,180,225] ],
[0.9375, [255,255,255], [255,255, 255]]
]),
]),
default: colormap([
[0, [45, 1, 121], [25, 1, 137] ],
[0.125, [25, 1, 137], [0, 6, 156] ],
[0.1875, [0, 6, 156], [7, 41, 172] ],
[0.25, [7, 41, 172], [22, 84, 187] ],
[0.3125, [22, 84, 187], [25, 125, 194] ],
[0.375, [25, 125, 194], [26, 177, 197] ],
[0.4375, [26, 177, 197], [23, 199, 193] ],
[0.47, [23, 199, 193], [25, 200, 170] ],
[0.50, [25, 200, 170], [21, 209, 27] ],
[0.5625, [21, 209, 27], [108, 215, 18] ],
[0.625, [108, 215, 18], [166, 218, 19] ],
[0.6875, [166, 218, 19], [206, 221, 20] ],
[0.75, [206, 221, 20], [222, 213, 19 ] ],
[0.7813, [222, 213, 19], [222, 191, 19]],
[0.8125, [222, 191, 19], [227, 133, 17] ],
[0.875, [227, 133, 17], [231, 83, 16] ],
[0.9375, [231, 83, 16], [220, 61, 48] ]
default: colormap([
[0, [45,1,121], [25,1,137] ],
[0.125, [25,1,137], [0,6,156] ],
[0.1875, [0,6,156], [7,41,172] ],
[0.25, [7,41,172], [22,84,187] ],
[0.3125, [22,84,187], [25,125,194] ],
[0.375, [25,125,194], [26,177,197] ],
[0.4375, [26,177,197], [23,199,193] ],
[0.47, [23,199,193], [25, 200,170] ],
[0.50, [25, 200,170], [21,209,27] ],
[0.5625, [21,209,27], [108,215,18] ],
[0.625, [108,215,18], [166,218,19] ],
[0.6875, [166,218,19], [206,221,20] ],
[0.75, [206,221,20], [222,213,19 ] ],
[0.7813, [222,213,19], [222, 191, 19]],
[0.8125, [222, 191, 19], [227,133,17] ],
[0.875, [227,133,17], [231,83,16] ],
[0.9375, [231,83,16], [220,61,48] ]
]),
]),
fastie: colormap([
[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] ]
]),
[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] ]
]),
stretched: colormap([
[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] ]
])
[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] ]
])
};
}

View File

@@ -24,13 +24,11 @@ module.exports = function Colormap(options, UI) {
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
callback: callback
});
}
@@ -40,5 +38,5 @@ module.exports = function Colormap(options, UI) {
draw: draw,
output: output,
UI: UI
};
};
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -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.",
"inputs": {
"colormap": {

View File

@@ -1,47 +1,47 @@
var _ = require('lodash');
module.exports = exports = function(pixels, contrast) {
let oldpix = _.cloneDeep(pixels);
contrast = Number(contrast);
if (contrast < -100) contrast = -100;
if (contrast > 100) contrast = 100;
contrast = (100.0 + contrast) / 100.0;
contrast *= contrast;
let oldpix = _.cloneDeep(pixels);
contrast = Number(contrast)
if (contrast < -100) contrast = -100;
if (contrast > 100) contrast = 100;
contrast = (100.0 + contrast) / 100.0;
contrast *= contrast;
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
var r = oldpix.get(i, j, 0) / 255.0;
r -= 0.5;
r *= contrast;
r += 0.5;
r *= 255;
if (r < 0) r = 0;
if (r > 255) r = 255;
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
var r = oldpix.get(i, j, 0) / 255.0;
r -= 0.5;
r *= contrast;
r += 0.5;
r *= 255;
if (r < 0) r = 0;
if (r > 255) r = 255;
var g = oldpix.get(i, j, 1) / 255.0;
g -= 0.5;
g *= contrast;
g += 0.5;
g *= 255;
if (g < 0) g = 0;
if (g > 255) g = 255;
var g = oldpix.get(i, j, 1) / 255.0;
g -= 0.5;
g *= contrast;
g += 0.5;
g *= 255;
if (g < 0) g = 0;
if (g > 255) g = 255;
var b = oldpix.get(i, j, 2) / 255.0;
b -= 0.5;
b *= contrast;
b += 0.5;
b *= 255;
if (b < 0) b = 0;
if (b > 255) b = 255;
var b = oldpix.get(i, j, 2) / 255.0;
b -= 0.5;
b *= contrast;
b += 0.5;
b *= 255;
if (b < 0) b = 0;
if (b > 255) b = 255;
pixels.set(i, j, 0, r);
pixels.set(i, j, 1, g);
pixels.set(i, j, 2, b);
pixels.set(i, j, 0, r);
pixels.set(i, j, 1, g);
pixels.set(i, j, 2, b);
}
}
}
return pixels;
};
return pixels;
}

View File

@@ -4,44 +4,42 @@
module.exports = function Contrast(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.contrast = options.contrast || defaults.contrast;
var output;
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.contrast = options.contrast || defaults.contrast;
var output;
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
function extraManipulation(pixels) {
pixels = require('./Contrast')(pixels, options.contrast);
return pixels;
}
function extraManipulation(pixels) {
pixels = require('./Contrast')(pixels, options.contrast)
return pixels
}
function output(image, datauri, mimetype) {
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback
});
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "contrast",
"name": "Contrast",
"description": "Change the contrast of the image by given value",
"inputs": {
"contrast": {

View File

@@ -1,50 +1,71 @@
var _ = require('lodash');
module.exports = exports = function(pixels, constantFactor, kernelValues, texMode) {
let kernel = kernelGenerator(constantFactor, kernelValues),
pixs = {
r: [],
g: [],
b: [],
};
module.exports = exports = function(pixels, constantFactor, kernelValues) {
let kernel = kernelGenerator(constantFactor, kernelValues), oldpix = _.cloneDeep(pixels);
kernel = flipKernel(kernel);
for (let y = 0; y < pixels.shape[1]; y++){
pixs.r.push([]);
pixs.g.push([]);
pixs.b.push([]);
for (let x = 0; x < pixels.shape[0]; x++){
pixs.r[y].push(pixels.get(x, y, 0));
pixs.g[y].push(pixels.get(x, y, 1));
pixs.b[y].push(pixels.get(x, y, 2));
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
let neighboutPos = getNeighbouringPixelPositions([i, j]);
let acc = [0.0, 0.0, 0.0, 0.0];
for (let a = 0; a < kernel.length; a++) {
for (let b = 0; b < kernel.length; b++) {
acc[0] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 0) * kernel[a][b]);
acc[1] += (oldpix.get(neighboutPos[a][b][0], neighboutPos[a][b][1], 1) * kernel[a][b]);
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);
acc[1] = Math.min(acc[1], 255);
acc[2] = Math.min(acc[2], 255);
pixels.set(i, j, 0, acc[0]);
pixels.set(i, j, 1, acc[1]);
pixels.set(i, j, 2, acc[2]);
}
}
}
return pixels;
const convolve = require('../_nomodule/gpuUtils').convolve;
const conPix = convolve([pixs.r, pixs.g, pixs.b], kernel, (pixels.shape[0] * pixels.shape[1]) < 400000 ? true : false);
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)));
function kernelGenerator(constantFactor, kernelValues) {
kernelValues = kernelValues.split(" ");
for (i = 0; i < 9; i++) {
kernelValues[i] = Number(kernelValues[i]) * constantFactor;
}
let k = 0;
let arr = [];
for (i = 0; i < 3; i++) {
let columns = [];
for (j = 0; j < 3; j++) {
columns.push(kernelValues[k]);
k += 1;
}
arr.push(columns);
}
return arr;
}
}
return pixels;
};
function kernelGenerator(constantFactor, kernelValues) {
kernelValues = kernelValues.split(' ');
for (i = 0; i < 9; i++) {
kernelValues[i] = Number(kernelValues[i]) * constantFactor;
}
let k = 0;
let arr = [];
for (y = 0; y < 3; y++) {
arr.push([]);
for (x = 0; x < 3; x++) {
arr[y].push(kernelValues[k]);
k += 1;
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;
}
}
return arr;
}

View File

@@ -1,45 +1,42 @@
module.exports = function Convolution(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.kernelValues = options.kernelValues || defaults.kernelValues;
options.constantFactor = options.constantFactor || defaults.constantFactor;
options.texMode = options.texMode || defaults.texMode;
var output;
options.kernelValues = options.kernelValues || defaults.kernelValues;
options.constantFactor = options.constantFactor || defaults.constantFactor;
var output;
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
function extraManipulation(pixels) {
pixels = require('./Convolution')(pixels, options.constantFactor, options.kernelValues, options.texMode);
return pixels;
}
function extraManipulation(pixels) {
pixels = require('./Convolution')(pixels, options.constantFactor, options.kernelValues);
return pixels;
}
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, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback
});
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -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>",
"inputs": {
"constantFactor":{
"type": "float",
"desc": "a constant factor, multiplies all the kernel values by that factor",
"default": 0.111,
"min": 0.001,
"max": 2,
"step": 0.001
"default": 0.1111,
"placeholder": 0.1111
},
"kernelValues": {
"type": "string",
"desc": "nine space separated numbers representing the kernel values in left to right and top to bottom format.",

View File

@@ -1,12 +1,12 @@
module.exports = function Crop(input, options, callback) {
module.exports = function Crop(input,options,callback) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var getPixels = require('get-pixels'),
savePixels = require('save-pixels');
savePixels = require('save-pixels');
options.x = parseInt(options.x) || defaults.x;
options.y = parseInt(options.y) || defaults.y;
getPixels(input.src, function(err, pixels){
getPixels(input.src,function(err,pixels){
options.w = parseInt(options.w) || Math.floor(pixels.shape[0]);
options.h = parseInt(options.h) || Math.floor(pixels.shape[1]);
options.backgroundColor = options.backgroundColor || defaults.backgroundColor;
@@ -17,29 +17,21 @@ module.exports = function Crop(input, options, callback) {
var iw = pixels.shape[0]; //Width of Original Image
var ih = pixels.shape[1]; //Height of Original Image
var backgroundArray = [];
backgroundColor = options.backgroundColor.substring(options.backgroundColor.indexOf('(') + 1, options.backgroundColor.length - 1); // extract only the values from rgba(_,_,_,_)
backgroundColor = backgroundColor.split(',');
backgroundColor = options.backgroundColor.split(" ");
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 array = [];
var newarray = new Uint8Array(4*w*h);
for (var n = oy; n < oy + h; n++) {
var offsetValue = 4 * w * n;
if(n < ih){
var start = n * 4 * iw + ox * 4;
var end = n * 4 * iw + ox * 4 + 4 * w;
var pushArray = Array.from(pixels.data.slice(start, end ));
array.push.apply(array, pushArray);
if(n<ih){
newarray.set(pixels.data.slice(n*4*iw + ox, n*4*iw + ox + 4*w),4*w*(n-oy));
} else {
array.push.apply(array, backgroundArray);
newarray.set(backgroundArray,4*w*(n-oy));
}
}
var newarray = Uint8Array.from(array);
pixels.data = newarray;
pixels.shape = [w, h, 4];
pixels.stride[1] = 4 * w;
pixels.shape = [w,h,4];
pixels.stride[1] = 4*w;
options.format = input.format;
@@ -55,7 +47,7 @@ module.exports = function Crop(input, options, callback) {
r.on('end', function(){
var data = Buffer.concat(chunks, totalLength).toString('base64');
var datauri = 'data:image/' + options.format + ';base64,' + data;
callback(datauri, options.format);
callback(datauri,options.format);
});
});
};

View File

@@ -22,7 +22,7 @@ module.exports = function CropModule(options, UI) {
setupComplete = false;
// This function is caled everytime the step has to be redrawn
function draw(input, callback) {
function draw(input,callback) {
var step = this;
@@ -32,7 +32,7 @@ module.exports = function CropModule(options, UI) {
var parseCornerCoordinateInputs = require('../../util/ParseInputCoordinates');
//parse the inputs
parseCornerCoordinateInputs(options, {
parseCornerCoordinateInputs(options,{
src: input.src,
x: { valInp: options.x, type: 'horizontal' },
y: { valInp: options.y, type: 'vertical' },
@@ -51,7 +51,7 @@ module.exports = function CropModule(options, UI) {
step.output = {
src: out,
format: format
};
}
// This output is accessible to the UI
options.step.output = out;
@@ -81,5 +81,5 @@ module.exports = function CropModule(options, UI) {
draw: draw,
output: output,
UI: UI
};
};
}
}

View File

@@ -2,7 +2,7 @@
module.exports = function CropModuleUi(step, ui) {
let inputWidth = 0,
inputHeight = 0;
inputHeight = 0;
// We don't have input image dimensions at the
// time of setting up the UI; that comes when draw() is triggered.
@@ -10,7 +10,7 @@ module.exports = function CropModuleUi(step, ui) {
// TODO: link this to an event rather than an explicit call in Module.js
function setup() {
let x = 0,
y = 0;
y = 0;
// display original uncropped input image on initial setup
showOriginal();
@@ -42,21 +42,20 @@ module.exports = function CropModuleUi(step, ui) {
converted[2],
converted[3]
);
$($(imgEl()).parents()[3]).find('input').trigger('change');
}
});
}
function convertToNatural(_x, _y, _width, _height) {
let displayWidth = $(imgEl()).width(),
displayHeight = $(imgEl()).height();
displayHeight = $(imgEl()).height();
// return in same order [ x, y, width, height ]:
return [
Math.floor(( _x / displayWidth ) * inputWidth),
Math.floor(( _y / displayHeight ) * inputHeight),
Math.floor(( _width / displayWidth ) * inputWidth),
Math.floor(( _height / displayHeight ) * inputHeight)
];
]
}
function remove() {
@@ -78,7 +77,7 @@ module.exports = function CropModuleUi(step, ui) {
}
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[1].value = y1;
options[2].value = width;
@@ -94,5 +93,5 @@ module.exports = function CropModuleUi(step, ui) {
setup: setup,
remove: remove,
hide: hide
};
};
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,33 +1,33 @@
{
"name": "crop",
"name": "Crop",
"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",
"inputs": {
"x": {
"type": "string",
"type": "integer",
"desc": "X-position (measured from left) from where cropping starts",
"default": 0
},
"y": {
"type": "string",
"type": "integer",
"desc": "Y-position (measured from top) from where cropping starts",
"default": 0
},
"w": {
"type": "string",
"type": "integer",
"desc": "Width of crop",
"default": "(50%)"
},
"h": {
"type": "string",
"type": "integer",
"desc": "Height of crop",
"default": "(50%)"
},
"backgroundColor": {
"type": "text",
"desc": "Background Color",
"default": "rgba(255,255,255,255)",
"id": "color-picker"
"type": "string",
"desc": "Background Color (Four space separated RGBA values)",
"default": "255 255 255 255",
"placeholder": "255 255 255 255"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#crop-module"

View File

@@ -1,34 +1,34 @@
/*
* Decodes QR from a given image.
*/
module.exports = function DoNothing(options, UI) {
module.exports = function DoNothing(options,UI) {
var output;
var jsQR = require('jsqr');
var getPixels = require('get-pixels');
// This function is called everytime a step has to be redrawn
function draw(input, callback, progressObj) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
getPixels(input.src, function(err, pixels) {
getPixels(input.src,function(err,pixels){
if (err) throw err;
if(err) throw err;
var w = pixels.shape[0];
var h = pixels.shape[1];
var decoded = jsQR(pixels.data, w, h);
var decoded = jsQR(pixels.data,w,h);
// 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){
// This output is accessible by Image Sequencer
step.output = {
src: datauri,
@@ -37,11 +37,9 @@ module.exports = function DoNothing(options, UI) {
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
callback: callback
});
}
@@ -51,5 +49,5 @@ module.exports = function DoNothing(options, UI) {
draw: draw,
output: output,
UI: UI
};
};
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "decode-qr",
"name": "Decode QR",
"description": "Search for and decode a QR code in the image",
"inputs": {
},

View File

@@ -28,11 +28,11 @@ module.exports = function Dither(pixels, type) {
for (let currentPixel = 0; currentPixel <= imageDataLength; currentPixel += 4) {
if (type === 'none') {
if (type === "none") {
// No dithering
pixels.data[currentPixel] = pixels.data[currentPixel] < threshold ? 0 : 255;
} else if (type === 'bayer') {
} else if (type === "bayer") {
// 4x4 Bayer ordered dithering algorithm
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);
pixels.data[currentPixel] = (map < threshold) ? 0 : 255;
} else if (type === 'floydsteinberg') {
} else if (type === "floydsteinberg") {
// FloydSteinberg dithering algorithm
newPixel = pixels.data[currentPixel] < 129 ? 0 : 255;
@@ -73,4 +73,4 @@ module.exports = function Dither(pixels, type) {
}
return pixels;
};
}

View File

@@ -1,40 +1,38 @@
module.exports = function Dither(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
module.exports = function Dither(options, UI){
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback, progressObj) {
function draw(input,callback,progressObj){
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
options.dither = options.dither || defaults.dither;
var step = this;
options.dither = options.dither || defaults.dither;
function extraManipulation(pixels) {
pixels = require('./Dither')(pixels, options.dither);
return pixels;
function extraManipulation(pixels) {
pixels = require('./Dither')(pixels, options.dither)
return pixels
}
function output(image, datauri, mimetype){
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback
});
}
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
return {
options: options,
draw: draw,
output: output,
UI: UI
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "dither",
"name": "Dither",
"description": "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.<a href='https://en.wikipedia.org/wiki/Dither'>Read more</a>",
"inputs": {
"dither": {

View File

@@ -1,33 +1,32 @@
module.exports = exports = function(pixels, options){
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.startingX = options.startingX || defaults.startingX;
options.startingX = options.startingX || defaults.startingX;
options.startingY = options.startingY || defaults.startingY;
var ox = Number(options.startingX),
var ox = Number(options.startingX),
oy = Number(options.startingY),
iw = pixels.shape[0],
ih = pixels.shape[1],
thickness = Number(options.thickness) || defaults.thickness,
ex = options.endX = Number(options.endX) - thickness || iw - 1,
ey = options.endY = Number(options.endY) - thickness || ih - 1,
ey = options.endY = Number(options.endY) -thickness || ih - 1,
color = options.color || defaults.color;
color = color.substring(color.indexOf('(') + 1, color.length - 1); // extract only the values from rgba(_,_,_,_)
color = color.split(',');
color = color.split(" ");
var drawSide = function(startX, startY, endX, endY){
for (var n = startX; n <= endX + thickness; n++){
for (var k = startY; k <= endY + thickness; k++){
for (var n=startX; n <= endX+thickness; n++){
for (var k=startY; k <= endY+thickness; k++){
pixels.set(n, k, 0, color[0]);
pixels.set(n, k, 1, color[1]);
pixels.set(n, k, 2, color[2]);
//pixels.set(n, k, 3, color[3]);
pixels.set(n, k, 3, color[3]);
}
}
};
}
drawSide(ox, oy, ox, ey); // Left
drawSide(ex, oy, ex, ey); // Right
drawSide(ox, oy, ex, oy); // Top
drawSide(ox, ey, ex, ey); // Bottom
return pixels;
};
}

View File

@@ -1,46 +1,44 @@
module.exports = function DrawRectangle(options, UI) {
var output;
var output;
function draw(input, callback, progressObj) {
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var step = this;
function changePixel(r, g, b, a) {
return [r, g, b, a]
}
function changePixel(r, g, b, a) {
return [r, g, b, a];
}
function extraManipulation(pixels) {
pixels = require('./DrawRectangle')(pixels, options)
return pixels
}
function extraManipulation(pixels) {
pixels = require('./DrawRectangle')(pixels, options);
return pixels;
}
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, {
output: output,
changePixel: changePixel,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback
});
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
changePixel: changePixel,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -1,4 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];
require('./Module'),
require('./info.json')
]

View File

@@ -1,5 +1,5 @@
{
"name": "draw-rectangle",
"name": "Draw Rectangle",
"description": "It draws a rectangle on the image",
"inputs": {
"startingX":{
@@ -33,10 +33,9 @@
},
"color":{
"type": "text",
"desc": "Select color",
"default": "rgba(20,20,20,1)",
"id": "color-picker"
"type": "string",
"desc": "RGBA values separated by a space",
"default": "0 0 0 255"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#draw-rectangle-module"

View File

@@ -1,9 +1,9 @@
module.exports = function Dynamic(options, UI) {
module.exports = function Dynamic(options,UI) {
var output;
// This function is called on every draw.
function draw(input, callback, progressObj) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
@@ -11,10 +11,10 @@ module.exports = function Dynamic(options, UI) {
var step = this;
// start with monochrome, but if options.red, options.green, and options.blue are set, accept them too
options.monochrome = options.monochrome || '(R+G+B)/3';
options.monochrome = options.monochrome || "(R+G+B)/3";
function generator(expression) {
var func = 'f = function (r, g, b, a) { var R = r, G = g, B = b, A = a;';
var func = 'f = function (r, g, b, a) { var R = r, G = g, B = b, A = a;'
func = func + 'return ';
func = func + expression + '}';
var f;
@@ -26,8 +26,8 @@ module.exports = function Dynamic(options, UI) {
channels.forEach(function(channel) {
if (options.hasOwnProperty(channel)) options[channel + '_function'] = generator(options[channel]);
else if (channel === 'alpha') options['alpha_function'] = function() { return 255; };
else options[channel + '_function'] = generator(options.monochrome);
else if (channel === 'alpha') options['alpha_function'] = function() { return 255; }
else options[channel + '_function'] = generator(options.monochrome);
});
function changePixel(r, g, b, a) {
@@ -45,13 +45,13 @@ module.exports = function Dynamic(options, UI) {
}
/* Functions to get the neighbouring pixel by position (x,y) */
function getNeighbourPixel(pixels, curX, curY, distX, distY) {
function getNeighbourPixel(pixels,curX,curY,distX,distY){
return [
pixels.get(curX + distX, curY + distY, 0),
pixels.get(curX + distX, curY + distY, 1),
pixels.get(curX + distX, curY + distY, 2),
pixels.get(curX + distX, curY + distY, 3)
];
pixels.get(curX+distX,curY+distY,0)
,pixels.get(curX+distX,curY+distY,1)
,pixels.get(curX+distX,curY+distY,2)
,pixels.get(curX+distX,curY+distY,3)
]
}
// via P5js: https://github.com/processing/p5.js/blob/2920492842aae9a8bf1a779916893ac19d65cd38/src/math/calculation.js#L461-L472
@@ -63,15 +63,15 @@ module.exports = function Dynamic(options, UI) {
// also via P5js: https://github.com/processing/p5.js/blob/2920492842aae9a8bf1a779916893ac19d65cd38/src/math/calculation.js#L116-L119
function constrain(n, low, high) {
return Math.max(Math.min(n, high), low);
}
};
if (start2 < stop2) {
return constrain(newval, start2, stop2);
} else {
return constrain(newval, stop2, start2);
}
}
};
function output(image, datauri, mimetype) {
function output(image,datauri,mimetype){
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
@@ -79,15 +79,13 @@ module.exports = function Dynamic(options, UI) {
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
changePixel: changePixel,
getNeighbourPixel: getNeighbourPixel,
getNeighborPixel: getNeighbourPixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
callback: callback
});
}
@@ -97,5 +95,5 @@ module.exports = function Dynamic(options, UI) {
draw: draw,
output: output,
UI: UI
};
};
}
}

Some files were not shown because too many files have changed in this diff Show More