Compare commits

...

522 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
Harsh Khandeparkar
3772f78f51 1000 contributions PR (#1008)
* Update PULL_REQUEST_TEMPLATE.md

* changes
2019-04-15 16:24:29 -05:00
Slytherin
6ba604550b Add codecov (#1014) 2019-04-15 15:58:58 -05:00
Harsh Khandeparkar
2f86dcb0c8 Fixed Service Worker (#976)
* Update cache.js

* Update cache.js

* Create sw.js

* Delete sw.js
2019-04-15 12:38:39 -05:00
dependabot[bot]
fd981634fa Bump commander from 2.19.0 to 2.20.0 (#980)
Bumps [commander](https://github.com/tj/commander.js) from 2.19.0 to 2.20.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v2.19.0...v2.20.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 12:33:00 -05:00
dependabot[bot]
142464bb8b Bump ora from 3.2.0 to 3.4.0 (#981)
Bumps [ora](https://github.com/sindresorhus/ora) from 3.2.0 to 3.4.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v3.2.0...v3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 12:32:09 -05:00
dependabot[bot]
78d9cd91e7 Bump jasmine-core from 3.3.0 to 3.4.0 (#986)
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/master/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v3.3.0...v3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 09:18:26 -05:00
Vibhor Gupta
e22eacf666 Add: white balance module (#1011)
* WIP

* added white balance and renamed temperature module

* import defaults

* white balance module test
2019-04-15 07:21:39 -05:00
Varun Gupta
c3e8c3fb74 Gl puppeteer (#1007)
* add geotiff

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* now running gl using localhost fixes #216

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* modularize api and fix tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* finishing up

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix benchmark.js

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-04-14 10:50:26 -05:00
aashna27
4e43c9123a Fixes Text-Overlay (#1004) 2019-04-12 10:11:00 -04:00
dependabot[bot]
914a172f5d Bump jquery from 3.3.1 to 3.4.0 (#1001)
Bumps [jquery](https://github.com/jquery/jquery) from 3.3.1 to 3.4.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.3.1...3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-11 04:42:32 -04:00
Lohitha
e4ddb04601 Add spinner while gif is generating (#991)
fixes #843
2019-04-08 19:47:26 -04:00
Harshith pabbati
edcc253029 fixed the bug (#999) 2019-04-08 08:26:39 -04:00
Terrence
51a38fe3cf More Modules option removed. Placeholder text added (#996)
* More Modules option removed. Placeholder text added

* 'A' changed to 'a' in placeholder text

* Update examples/lib/intermediateHtmlStepUi.js

Suggested update

Co-Authored-By: teisenhower <47988669+teisenhower@users.noreply.github.com>
2019-04-07 13:12:18 -04:00
Varun Gupta
e4e4548c09 add canvas resize module (#994)
* add canvas resize module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-04-07 12:41:14 -04:00
Vajean Stan
7cf96df1ee Removed redundant parameters in ImageSequencer.js (#967)
* Removed redundant parameters in ImageSequencer.js

* Re-added loadImages, deleted loadImage

* Left both loadImage and loadImages in

I think I need more details to the last phrase in the instructions, telling me to remove the export of loadImages, I tried deleting that line and cannot pass the test.
2019-04-05 18:03:04 -04:00
Harsh Khandeparkar
2a0eff41f4 Fix insert step and allow "closing" it (#655)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* fix insert step button

* add icon

* add dist

* use normal functions

* use normal functions

* no lag

* changes

* changes

* changes

* Update intermediateHtmlStepUi.js

* toggleDiv global

- Globalised toggleDiv
- toggleDiv has default callback which does nothing.
2019-04-05 15:08:42 -04:00
Harsh Khandeparkar
b95728f95c Create fto-template.md (#977)
* Create fto-template.md

* Create first-timers.yml
2019-04-05 14:42:34 -04:00
Harshith pabbati
d63aab79a6 Added doc for grid-overlay (#983) 2019-04-05 14:37:17 -04:00
Harshith pabbati
0e7323efa9 Grid-Overlay module. (#974)
* Grid-Overlay module

* Added the X and Y for inputs
2019-04-03 08:46:57 -04:00
Harshith pabbati
1de170c978 made few changes to css (#975) 2019-04-02 09:37:39 -04:00
Jeffrey Warren
9a666a2f06 add maintainability badge from codeclimate 2019-04-01 14:33:02 -04:00
Harshith pabbati
985c67847e Changes to make the insert-step disable at the first step (#968) 2019-04-01 10:36:45 -04:00
Jeffrey Warren
690c126f41 ui-tweaks (#960) 2019-03-30 12:47:56 -04:00
Harshith pabbati
bc1151c340 Made it to work (#958) 2019-03-29 18:21:01 -04:00
Jeffrey Warren
32268c54df remove container class from step div (#956) 2019-03-28 21:35:10 -04:00
dependabot[bot]
12df02a0fd Bump jsdom from 13.2.0 to 14.0.0 (#845)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 13.2.0 to 14.0.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/13.2.0...14.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-28 21:32:05 -04:00
MichaelLin250
a51644963a TRYING SO HARD TO FIX IT (#950) 2019-03-28 21:29:41 -04:00
Harshith pabbati
9f524615a5 Bootstrap panel (#942)
* Bootstrap panel

* Indentation.

* css tidying

* more tweaks
2019-03-28 20:59:21 -04:00
aashna27
8ad171ee56 Tests added (#943) 2019-03-27 07:49:42 -04:00
vaari gupta
a8757a888a Improved Footer (#904)
* improved footer

* corrected Footer

* Delete image-sequencer-ui.js

* Delete image-sequencer-ui.min.js

* Delete image-sequencer.js

* Delete image-sequencer.min.js
2019-03-26 18:33:48 -04:00
Harsh Khandeparkar
24fb83a565 Delete image-sequencer-ui.js (#941)
* Delete image-sequencer-ui.js

* fix link
2019-03-25 16:53:06 -04:00
aashna27
60cfcb4d30 Added Text Overlay module (#917) 2019-03-25 15:58:02 -04:00
Jeffrey Warren
488bbd86da Rearrange buttons in UI (#936) 2019-03-25 15:57:18 -04:00
Harsh Khandeparkar
a923f48c87 gitignore dist and update links (#908)
* Update .gitignore

* Delete image-sequencer-ui.min.js

* Delete image-sequencer.js

* Delete image-sequencer.min.js

* Update README.md

* Update README.md

* Update CONTRIBUTING.md

* Update .npmignore

* Update README.md

* Update .npmignore

* Update CONTRIBUTING.md
2019-03-25 15:55:34 -04:00
dependabot[bot]
15e93f09bd Bump grunt from 1.0.3 to 1.0.4 (#939)
Bumps [grunt](https://github.com/gruntjs/grunt) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/gruntjs/grunt/releases)
- [Changelog](https://github.com/gruntjs/grunt/blob/master/CHANGELOG)
- [Commits](https://github.com/gruntjs/grunt/compare/v1.0.3...v1.0.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 11:01:52 -04:00
dependabot[bot]
eb12d061ee Bump looks-same from 7.1.1 to 7.2.0 (#940)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.1.1 to 7.2.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/commits/v7.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 11:01:42 -04:00
Harsh Khandeparkar
95efe812c3 Rename White balance to ColorTemperature (#931)
* Update and rename src/modules/WhiteBalance/Module.js to src/modules/ColorTemperature/Module.js

* Rename src/modules/WhiteBalance/index.js to src/modules/ColorTemperature/index.js

* Update and rename src/modules/WhiteBalance/info.json to src/modules/ColorTemperature/info.json

* Update Modules.js

* Update MODULES.md

* Update MODULES.md

* Update Module.js

* Update info.json
2019-03-25 10:11:55 -04:00
rohithGoudM
9be102e1dd Fixed Unresponsive Select Step Box (#927)
* The cursor changes to pointer when hovered over select element

* Cursor to pointer changes added to demo.css

* adding csrtoptr class directly to dist file

* small bug in ui fixed through bootstrap

* small bug in ui fixed through bootstrap

* Fixed unresponsive bug in ui with bootstrap

* all changes have been deleted regarding the cursor bug. only unresponsive bug has been solved
2019-03-25 10:11:09 -04:00
Jeffrey Warren
b0a00a71d3 Update diagram (#921) 2019-03-24 12:08:57 -04:00
dependabot[bot]
001ad61954 Bump looks-same from 7.1.0 to 7.1.1 (#907)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-22 19:21:12 -04:00
Jeffrey Warren
ca8b7ecb95 Update CONTRIBUTING.md 2019-03-22 14:37:22 -04:00
Harshith pabbati
33dcb5794f clear cache offline button (#910) 2019-03-21 18:51:36 -04:00
Harshith pabbati
9ffd60c707 Seo tags for google search (#914)
* Seo tags for google search

* changes

* changes
2019-03-21 16:50:24 -04:00
Harsh Khandeparkar
32bd372139 Minify JS for production (#897)
* Create prod.js

* Delete prod.js

* add production task

* add grunt tasks to contributing file

* add default task.
2019-03-20 23:19:18 -04:00
Slytherin
bae2013243 Fixed quick buttons issue (#905) 2019-03-20 17:21:57 -04:00
Varun Gupta
cb53efbe21 redid import-image and fix ExportBin fixes #899 (#900)
* redid import-image and fix ExportBin fixes #899

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* 3.0.1

* bypass import-image

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-03-20 13:53:02 -04:00
MAYANK CHHIPA
21ff486618 Add Dropdown Transitions (#881)
* Add Dropdown Transitions

* Add Dropdown Transitions

* Update defaultHtmlStepUi.js

* Add Dropdown Transitions

* Add Dropdown Transitions

* Add Dropdown Transitions
2019-03-19 15:28:05 -04:00
Harsh Khandeparkar
951afdbc4f add grunt build to setup script (#895) 2019-03-19 11:50:09 -04:00
aashna27
709df84cb2 Corrected view (#867) 2019-03-19 11:41:39 -04:00
Harsh Khandeparkar
f852730d98 Is Nightly Completed (#893)
* beta demo

* config.yml

* Update config.yml

* Update ISSUE_TEMPLATE.md

* Update package.json

* mistake

* mistake
2019-03-19 10:25:06 -04:00
Vibhor Gupta
e5cf6a311f Add: Exposure Module (#721)
* exposure module

* requested changes

* update module
2019-03-19 08:02:28 -04:00
Harsh Khandeparkar
b8beec96be Revise Gruntfile (#887) 2019-03-18 19:10:03 -04:00
Slytherin
5e33c69736 Add search functionality in choose Module select (#750)
* Add Search functionality in choose functionalityoption

* Adds grunt build changes

* Adds node module for selectize and changed path
2019-03-18 17:28:19 -04:00
Slytherin
bd68245a12 Update Readme.md that includes importJSON section (#744)
* Update Readme.md that includes importJSON docs

* Adds command JSON object step addition format to README.md

* Added reference to the appropriate test

* Resolved missing rebase

* Deleted images in test_outputs directory and put it in .gitignore file
2019-03-18 16:37:44 -04:00
Harsh Khandeparkar
c6457323cc Complete Edge Detect Module (#771)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* fix insert step button

* add icon

* add dist

* use normal functions

* use normal functions

* add new function

* add dist

* remove console logs

* changes

* refactor

* add dist

* Bump looks-same from 5.0.2 to 6.0.0 (#729)

Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v5.0.2...v6.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Setup UI testing (#720)

* default sequencer ui test

* default step ui test suite

* intermediate step ui test

* preview ui test suite

* url methods test suite

* add set url params method test suite

* argument call tests

* test directory refactor

* travis fix

* CLI code refactor (#665)

* CLI refactor

* es6 rollback

* Travis fix

* syntax fix

* clustered require statements

* travis debug

* travis debug

* Added line that selects the "More modules..." after adding a step. (#713)

* Added line making module selection correct after adding a step

* Added line with appropriate module selection

* Add: Module tests (#748)

* WIP

* module testing harness

* adjustments

* Fix choose file option and insert step functionality (#712)

* Fix choose file option

* changes

* Parse info.json to set module defaults (#650)

* changes

* changes

* changes

* changes

* changes

* changes

* Update package-lock.json

* Bump jsqr from 1.1.1 to 1.2.0 (#749)

Bumps [jsqr](https://github.com/cozmo/jsQR) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Bump jsqr from 1.1.1 to 1.2.0 (#749)

Bumps [jsqr](https://github.com/cozmo/jsQR) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* dist

* changes

* working

* final touches

* revert mapTypes

* proper revert

* Fix arctangent

* working hysteresis

* hysteresis optional
2019-03-17 17:05:24 -04:00
aashna27
e1a113cde1 Added tests for more modules (#752) 2019-03-16 12:26:40 -04:00
MAYANK CHHIPA
24fb0ca9e4 Adds a reference to sequencer in replaceImage() (#865)
* Fixes #864

* Adds a reference to sequencer in replaceImage()
2019-03-16 12:24:32 -04:00
Harshith pabbati
a2fb2689a6 Made the flip image work in correct way (#854) 2019-03-14 19:32:29 -04:00
Harsh Prabhu
0be9e3f33b Centered the cropped image (#705)
* Updated demo.css

* Updated defaultHtmlStepUI.js

* Updated defaultHtmlStepUI.js

* Updated defaultHtmlStepUI.js

* Updated demo.css

* Updated defaultHtmlStepUi.js

* Updated defaultHtmlStepUi.js

* Added semi-colons in demo.css

* removed the style attribute from the img element
2019-03-14 19:07:18 -04:00
Jeffrey Warren
30e9f359d5 change insertPreview quick add defaults (#855) 2019-03-14 18:59:00 -04:00
maks-ostashkevich
3c1b6f2019 Change Footer Links In index.html (#848)
* Lines 202, 205, 211 have been changed in examples/index.html.

* Update examples/index.html line 211

Co-Authored-By: maks-ostashkevich <33810779+maks-ostashkevich@users.noreply.github.com>

* Update examples/index.html line 202

Co-Authored-By: maks-ostashkevich <33810779+maks-ostashkevich@users.noreply.github.com>

* Update examples/index.html line 205

Co-Authored-By: maks-ostashkevich <33810779+maks-ostashkevich@users.noreply.github.com>
2019-03-14 11:06:28 -04:00
Varun Gupta
96299ed6f7 3.0.0 (#783) 2019-03-14 11:05:15 -04:00
Slytherin
2f21bec80a Restructure API (#824)
* Change addsteps(), loadImages(), run() and default UI

* Restructure API completely

* Add updated dist files

* Removed extra comments

*  Indentation improved

* Update README.md
2019-03-14 11:04:02 -04:00
dependabot[bot]
3d1bbe5940 Bump looks-same from 7.0.0 to 7.1.0 (#853)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v7.0.0...v7.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-14 10:58:08 -04:00
Lohitha
0865bc44d2 Document the new modules and docs-link for all modules (#841)
* Document the new modules and doc-link for all modules

This commit introdueces new modules to image-sequencer
	- Dither
	- Draw Rectangle
	- Paint Bucket
	- Tint
	- Threshold
	- WhiteBalance

fixes #719

* Update docs/MODULES.md

Co-Authored-By: lohitha02 <lohithabhagam123@gmail.com>

* Update MODULES.md

* Update info.json

* Update MODULES.md

* Update info.json

* Update info.json
2019-03-08 12:18:37 -05:00
Mridul97
055b17c75f Add replace color module (#724)
* Add color separation module

* changes

* changes

* changes

* changes

* Add test
2019-03-04 19:19:39 -05:00
dependabot[bot]
bf2fd7ede6 Bump ora from 3.1.0 to 3.2.0 (#830)
Bumps [ora](https://github.com/sindresorhus/ora) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v3.1.0...v3.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 17:55:14 -05:00
Harsh Khandeparkar
1e08d7c1da Map types to html types (#754)
* fix insert step button

* add dist

* add new function

* remove console logs

* refactor

* Setup UI testing (#720)

* default sequencer ui test

* default step ui test suite

* intermediate step ui test

* preview ui test suite

* url methods test suite

* add set url params method test suite

* argument call tests

* test directory refactor

* travis fix

* CLI code refactor (#665)

* CLI refactor

* es6 rollback

* Travis fix

* syntax fix

* clustered require statements

* travis debug

* travis debug

* Added line that selects the "More modules..." after adding a step. (#713)

* Added line making module selection correct after adding a step

* Added line with appropriate module selection

* Add: Module tests (#748)

* WIP

* module testing harness

* adjustments

* Update package-lock.json

* Bump jsqr from 1.1.1 to 1.2.0 (#749)

Bumps [jsqr](https://github.com/cozmo/jsQR) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* refactor without spread syntax
2019-03-04 17:54:28 -05:00
Harsh Khandeparkar
ac57b32ec6 Added New FlipImage Module (#696)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* rebase and rebuild

* add dist

* flip image

* Changes

* Changes

* add dist

* missed one
2019-03-02 13:40:04 -05:00
Aneal Sharma
9f5a7bb49a Update "Installation" section of README.md (#817)
* Update "Installation" section of README.md

The following changes make the section more concise by removing unnecessary words.

* Update README.md

* Updated README.md further

-made additional grammatical and word choice improvements
2019-03-01 13:28:54 -05:00
dependabot[bot]
af033d15c6 Bump looks-same from 5.1.0 to 7.0.0 (#823)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 5.1.0 to 7.0.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v5.1.0...v7.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-01 10:57:48 -05:00
Mary Ramirez
273f1eb494 Update index.html (#815)
Replaced line 214 with by changing the "improve this tool" button to primary.
2019-02-27 19:25:56 -05:00
Lokesh
6a450c743e Format the "Take a Photo" button (#739)
* Update index.html

added bootstrap classes btn brn-default btn-md for Take a photo button

* changed brn-default btn-primary

* changed button color and size
2019-02-23 07:45:55 -06:00
igorwilbert
bed23c8974 Adds data model diagram in README (#811) 2019-02-22 13:29:38 -06:00
aashna27
3c5f0a2a30 Typecast removed (#802) 2019-02-21 18:21:12 -06:00
aashna27
ffed3d1af1 Corrected default view for Saturation module (#772)
* Corrected default view for Saturation module

* package lock
2019-02-21 17:14:05 -06:00
aashna27
92aaaa9a42 RGB values on hover (#808) 2019-02-21 13:38:49 -08:00
Slytherin
6dd7738476 Adds "Add QR" module (#736)
* Adds Add QR module

* Grunt build changes

* Rremoved copyPixels function and added test for QR module

* Resolved test fail issues

* Adds look same test

* Change default to get from info.json
2019-02-21 10:02:24 -08:00
Lohitha
600ddece58 Fix "Save As" overflow on small screens (#795)
* Fixed #789 issue

* Fix #789 Save As overflow on small screens
2019-02-20 17:01:42 -08:00
Vibhor Gupta
29b0571c64 Add: UI test script to Travis (#791)
* codecov

* travis ui test fix

* undo

* fix
2019-02-20 16:48:14 -08:00
aashna27
cc0c5411d9 Fixes Crop module (#803) 2019-02-20 16:29:48 -08:00
Harshith pabbati
194e6fc441 Added a footer to the main page (#776)
* Added the footer to the main page

* Added the footer with link of the github issues
2019-02-20 10:37:54 -08:00
Harshith pabbati
fdb38f7fdf Added the resize quick button (#782)
* Added the resize module

* Added the resize quick button

* Made the icon to fit into the box

* Added the footer to the main page

* Added the resize quick button

* Added the resize quick button

* Added the resize quick button
2019-02-17 18:16:15 -06:00
Slytherin
c3abdaf3aa Add sequencer.getSteps() (#777)
* create getSteps() and test it

* Adds test with new sequencer instance and updated Readme
2019-02-17 18:14:59 -06:00
Varun Gupta
761142d9d3 createMetaModule generator (#779)
* initial createMetaModule

* fixes

* fix

* Update createMetaModule.js

* Update createMetaModule.js

* refactor and fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update ndvi-colormap

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-02-16 22:33:45 +05:30
Varun Gupta
81b06d1b42 Benchmarks (#781)
* benchmarks initial try

* added test to package.json

* Update benchmark.js

* Update benchmark.js

* Update benchmark.js

* Update benchmark.js

* bigger image

* change load-Image to browser only and fix benchmark

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* run on same image

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-02-16 21:25:23 +05:30
Varun Gupta
75dc23fb55 Improve Code Quality and Optimize (#763)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-02-16 11:05:32 +05:30
Mridul97
f42aa2fd67 changes (#704) 2019-02-15 13:36:33 -05:00
dependabot[bot]
e0ed73a24e Bump bootstrap from 3.4.0 to 3.4.1 (#769)
Bumps [bootstrap](https://github.com/twbs/bootstrap) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v3.4.0...v3.4.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-14 12:29:40 -05:00
dependabot[bot]
c2bc12a112 Bump tape from 4.10.0 to 4.10.1 (#770)
Bumps [tape](https://github.com/substack/tape) from 4.10.0 to 4.10.1.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v4.10.0...v4.10.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-14 07:47:12 -05:00
Varun Gupta
fa30c1b30f Opaque meta module + test - colorbar (#764)
* opaque colorbar test

* build

* rebase + build

* fixed opaque meta modules yay

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add test and prevent internal logs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* Update meta-modules.js
2019-02-13 10:36:11 -05:00
Sand
53db6bd2ce Assigned ref.images[image].steps[i] to a variable to stop duplication (#756) 2019-02-11 19:19:41 -05:00
aashna27
f4a80a0490 Default values added for few modules (#757) 2019-02-11 19:18:49 -05:00
dependabot[bot]
9836314f1f Bump ora from 3.0.0 to 3.1.0 (#758)
Bumps [ora](https://github.com/sindresorhus/ora) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v3.0.0...v3.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-11 19:18:09 -05:00
dependabot[bot]
6e193d48fc Bump tape from 4.9.2 to 4.10.0 (#759)
Bumps [tape](https://github.com/substack/tape) from 4.9.2 to 4.10.0.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v4.9.2...v4.10.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-11 19:17:47 -05:00
igorwilbert
1a0ae054c8 New layout for Save and Add areas (#745) 2019-02-09 08:54:50 -05:00
Jeffrey Warren
b638ceb1db Change default of Rotate module to 90 (#734) 2019-02-08 17:37:40 -05:00
aashna27
f09df0d042 Fixes Decode-qr (#680) 2019-02-08 17:35:32 -05:00
jywarren
044a120468 bumped to v2.5.0 2019-02-08 13:24:20 -05:00
Mridul97
2d8b93020a Add tint module (#701)
* Add tint module

* rebased, rebuilt
2019-02-08 13:20:47 -05:00
Mridul97
90c57af332 Change threshold range (#700)
* change tolerance values

* changes
2019-02-08 13:03:20 -05:00
Harsh Khandeparkar
78cbaa262b rebuild rebase (#674) 2019-02-08 12:10:24 -05:00
aashna27
ddde6e1e2e Added Threshold (#722) 2019-02-08 11:50:45 -05:00
Harsh Khandeparkar
2d8bb53402 Used pixels.set To Refactor DrawRectangle (#690)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* use pixel.set for drawRectangle

* chnage thickness
2019-02-08 11:21:24 -05:00
dependabot[bot]
b47de40292 Bump jsqr from 1.1.1 to 1.2.0 (#749)
Bumps [jsqr](https://github.com/cozmo/jsQR) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-07 18:01:44 -05:00
jywarren
0a091a611f version bump to 2.4.0 2019-02-06 19:52:05 -05:00
Aneal Sharma
2274ce6785 Update "Why" section in README.md (#742) 2019-02-06 19:30:04 -05:00
Jeffrey Warren
58c6cbff24 Update package-lock.json 2019-02-06 16:32:01 -05:00
Mridul97
6153dbfdaa Parse info.json to set module defaults (#650)
* changes

* changes

* changes

* changes

* changes

* changes
2019-02-06 11:10:54 -05:00
Mridul97
6b305a02f5 Fix choose file option and insert step functionality (#712)
* Fix choose file option

* changes
2019-02-05 11:32:16 -05:00
Vibhor Gupta
57e4849d35 Add: Module tests (#748)
* WIP

* module testing harness

* adjustments
2019-02-05 11:31:13 -05:00
Gabriel Ting
3081dccf19 Added line that selects the "More modules..." after adding a step. (#713)
* Added line making module selection correct after adding a step

* Added line with appropriate module selection
2019-02-01 12:28:49 -05:00
David Koch
fa047ce6a9 minor fix for better readability (#730)
* minor fix for better readability

* added one '#'
2019-01-31 13:01:24 -05:00
Vibhor Gupta
d0bf9de71a CLI code refactor (#665)
* CLI refactor

* es6 rollback

* Travis fix

* syntax fix

* clustered require statements

* travis debug

* travis debug
2019-01-31 13:01:03 -05:00
Vibhor Gupta
0cd3156c06 Setup UI testing (#720)
* default sequencer ui test

* default step ui test suite

* intermediate step ui test

* preview ui test suite

* url methods test suite

* add set url params method test suite

* argument call tests

* test directory refactor

* travis fix
2019-01-31 12:56:34 -05:00
dependabot[bot]
8880a580dd Bump looks-same from 5.0.2 to 6.0.0 (#729)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v5.0.2...v6.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-30 06:00:00 -06:00
dependabot[bot]
c445070937 Bump jsdom from 13.1.0 to 13.2.0 (#709)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 13.1.0 to 13.2.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/13.1.0...13.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 09:04:41 -03:00
dependabot[bot]
d792f21147 Update jsdom requirement from ^11.12.0 to ^13.1.0 (#703)
Updates the requirements on [jsdom](https://github.com/jsdom/jsdom) to permit the latest version.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/commits/13.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-23 21:15:24 -03:00
Nicole Ortiz García
ad60c91d6b Updating demo.css to only remove padding on sliders (#702)
* Update demo.css

removed padding only on sliders -- added the attribute selector [type="range"] on the demo.css file.

* Update demo.css

removed space between .form-control and [type="range"] -- pull request review.
2019-01-23 19:09:53 -03:00
aashna27
3c2d6542dc Added second spinner (#691) 2019-01-23 19:08:53 -03:00
atsutton
b64e7cefc0 Switch to npm for gifshot (#689)
* Switch to npm for gifshot

* Added a refreshed package-lock.json

* Updated package.json and package-lock.json

* Cleared cache, resync with trunk
2019-01-23 19:08:11 -03:00
Harpinder
eb3b3df800 Changed New PR Welcome Comment issue: #684 (#688) 2019-01-22 18:16:13 -04:00
Mridul97
0e6e1837a6 Use browserify for ui js files and refactor ui js files (#668)
* changes

* changes

* changes
2019-01-22 18:15:23 -04:00
Maseu
dc361a3ab8 Fixed Import Image Text Overflow (#695)
* Replace dropzone id with dropzone class

* Added dropzone class to div container

* Updated dropZone listener

* Changed #dropzone input to .dropzone input
2019-01-22 16:26:04 -04:00
Slytherin
3d2d7844b6 Added thumbnails to insert preview. (#653)
* Adds thumbnail to insert step view

* removed redundant code

* Resolved merge conflicts

* Resolved merge conflicts

* made changes in intermediateHtmlStepUi

* Update intermediateHtmlStepUi.js
2019-01-22 16:24:59 -04:00
Slytherin
8fd4efc621 Add tests for notify() (#686)
* Added HTML-UI test

* Added test for notify()

* Updated Readme's
2019-01-22 10:43:39 -04:00
Harsh Prabhu
413a235594 updated PULL-REQUEST-TEMPLATE.md (#682)
* updated PULL-REQUEST-TEMPLATE.md

* Updated PULL-REQUEST_TEMPLATE.md
2019-01-22 09:14:19 -04:00
Himanshu
0e87c8b1df Remove console logs (#685)
* Removed logs

* Update demo.js
2019-01-22 09:13:50 -04:00
Mridul97
4fd814dd95 Add paint bucket module (#556)
* Add paint-bucket

* Add tolerance input
2019-01-22 09:03:42 -04:00
Slytherin
17d79c4b44 Fixed PR template test command (#677) 2019-01-17 18:52:20 -05:00
Slytherin
85a53325d2 Changes travis configuration to remove test for node v4 (#683) 2019-01-17 17:43:35 -05:00
Slytherin
81719a9e13 Stops loading of blend-module when offset unavailable (#654)
* Stops loading of blend-module when offset unavailable

* Added improvements

* Update demo.css

* Update notification.js

* Update defaultHtmlStepUi.js

* Update Module.js

* Update notification.js

* adds generic UI function to user-interface

* Added changes
2019-01-16 17:41:33 -05:00
VIRIK JAIN
fc02e7aea0 Add CODE_OF_CONDUCT.md (#681) 2019-01-16 22:55:54 +05:30
Mridul97
f68983d6d7 Fix toggle-able collapse (#651)
* fix toggle

* changes

* dist changes

* changes

* changes

* changes

* changes
2019-01-14 17:05:23 -05:00
Harsh Khandeparkar
b5fcba3c54 Refactor Draw Rectangle Module (#664)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* change template

* refactor drawRectangle

* changes

* changes
2019-01-14 15:57:49 -05:00
Jeffrey Warren
f6b1f7b201 Add code climate coverage reporting in Travis (#635)
* Add code climate coverage reporting in Travis

* Update .travis.yml
2019-01-14 15:53:58 -05:00
HarshKhandeparkar
2399e511a0 New pr template (#663)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* change template
2019-01-12 08:47:13 -05:00
dependabot[bot]
cfdb54359c Bump looks-same from 5.0.1 to 5.0.2 (#652)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v5.0.1...v5.0.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-11 12:37:10 -05:00
Mridul97
9e5f252fd4 Fix scroll up button (#638)
* fix scroll-up button

* dist changes

* changes

* changes
2019-01-10 21:22:51 -05:00
aashna27
2e9689b905 TakePhoto fixes (#641) 2019-01-10 18:11:03 -05:00
Mridul97
c72beb7359 test brightness module (#624) 2019-01-09 14:24:17 -05:00
aashna27
e5d26815d7 toggle-able collapse added for modules (#636) 2019-01-08 15:22:25 -05:00
aashna27
73b917f036 Header opens a new page (#619) 2019-01-08 15:18:32 -05:00
Mridul97
0248bc7124 Compilation of ui js files (#627)
* changes

* changes
2019-01-08 11:40:28 -05:00
Mridul97
89345f32b3 Add a 'Start a new sequence' button (#589)
* add start a new sequence button

* changes

* reset sequence

* changes

* changes

* changes

* changes

* changes
2019-01-07 18:22:51 -05:00
HarshKhandeparkar
4e5f8728fa Fixed Save Button (#562)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* fix save button

* cleanup

* fix update initValue

* fix select type inputs

* fix integer type values

* fix integer type values

* cleanup

* changes and cleanup

* changes

* changes

* better solution

cleanup

* change detection finalized

* Fix <form> placement

* fix form ending

* changes

* cleanup

* fix merge conflicts

* better event listener

* cleanup

* cleanup

* Changes

* cleanup
2019-01-07 15:16:25 -05:00
Bhavay Anand
c2477bc3f7 fixed excessive space around thumbnail grid (#629) 2019-01-07 10:41:04 -05:00
Vibhor Gupta
ef4a4d3055 removed crop div (#623) 2019-01-07 09:40:53 -05:00
aashna27
20d49456fd Modified style for step remove notification (#620)
* modified style for step remove notification

* Update defaultHtmlStepUi.js
2019-01-06 14:44:25 -05:00
aashna27
2aa7e9b96c Dithering module added (#617) 2019-01-06 10:47:23 -05:00
jywarren
52c9c35398 version bump 2019-01-05 21:01:58 -05:00
Vibhor Gupta
a522e13613 media query for buttons (#583)
* media query for buttons

* easy fix

* quick icon scroll for small screens

* rebuild
2019-01-05 20:53:45 -05:00
Jeffrey Warren
f41f564bd9 npm audit (#614) 2019-01-05 20:51:24 -05:00
Vibhor Gupta
1a98247858 import/export bug fix (#608) 2019-01-05 20:37:42 -05:00
Mridul97
4369137336 update value below the slider (#565)
* update value below the slider

* changes
2019-01-05 20:17:39 -05:00
Mridul97
595d66ecd5 remove extra clear cache button and isolate cache code (#609)
* remove extra clear cache button

* isolate cache code

* changes
2019-01-05 17:28:11 -05:00
Mridul97
6d9f656a1e Show a message where to find saved sequence on saving a sequence (#586)
* show message on save sequence

* chaanges

* changes
2019-01-05 14:32:18 -05:00
Mridul97
69ed689ad7 refactor/speed-up brightness module (#558)
* refactor/speed-up brightness module

* changes
2019-01-05 11:23:29 -05:00
Jeffrey Warren
107b4c22e4 new defaults (#607) 2019-01-04 18:13:28 -05:00
jywarren
e5d36ca317 demo tweak 2019-01-04 15:08:41 -05:00
aashna27
eb595d6139 added sliders (#603) 2019-01-04 14:35:39 -05:00
MargaretAN9
2bdd532848 Fix fastie (#594)
* fixed fastie

* fixed greyscale (#593)

* add local to locally stored modules (#596)

* Add drawing rectangles module (#566)

* add drawing rectangle module

* changes

* White balance module (#585)

* white baalance module

* improved algorithm

* limit check

* Ability to set background color when "over cropping" to enlarge canvas (#563)

* ability to set background color when over cropping to enlarge canvas

* changes

* Clarify that saved sequence will only be available in this browser (#587)

* clarify that saved sequence will only be available in this browser

* changes

* changes

* changes

* Added a function to sequencer and then made the functionality available to crop and overlay module. (#592)

* Add manifest.json and cache static assets for offline use (#331)

* Add manifest.json

* cache static assets for offline use

* update cache

* add meta theme-color and change static files to be cache

* cache the files on network request

* caching on first run

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add a button to clear cache

* add styling to clear cache link

* Update Modules.js (#452)

I've arranged the modules in alphabetical order.

* Added a function to parse Input coordinates and added the functionality for crop and overlay modules

* Added changed dist files

* Revert "Added changed dist files"

This reverts commit dbda25a228.

* Changed function name and added the functionaity to src/utils folder

* Added unit test

* Added unit test to /test/util

* Add border thickness and color in DrawRectangle module (#602)

* added border thickness functionality

* add color functionality

* Bump tape from 4.9.1 to 4.9.2 (#579)

Bumps [tape](https://github.com/substack/tape) from 4.9.1 to 4.9.2.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v4.9.1...v4.9.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Bump looks-same from 4.1.0 to 5.0.1 (#559)

Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 4.1.0 to 5.0.1.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v4.1.0...v5.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Bump jsqr from 0.2.2 to 1.1.1 (#532)

Bumps [jsqr](https://github.com/cozmo/jsQR) from 0.2.2 to 1.1.1.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Update color drop down (#595)

* updated drop down

* fixed greyscale (#593)

* add local to locally stored modules (#596)

* Add drawing rectangles module (#566)

* add drawing rectangle module

* changes

* White balance module (#585)

* white baalance module

* improved algorithm

* limit check

* Ability to set background color when "over cropping" to enlarge canvas (#563)

* ability to set background color when over cropping to enlarge canvas

* changes

* Clarify that saved sequence will only be available in this browser (#587)

* clarify that saved sequence will only be available in this browser

* changes

* changes

* changes

* Added a function to sequencer and then made the functionality available to crop and overlay module. (#592)

* Add manifest.json and cache static assets for offline use (#331)

* Add manifest.json

* cache static assets for offline use

* update cache

* add meta theme-color and change static files to be cache

* cache the files on network request

* caching on first run

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add a button to clear cache

* add styling to clear cache link

* Update Modules.js (#452)

I've arranged the modules in alphabetical order.

* Added a function to parse Input coordinates and added the functionality for crop and overlay modules

* Added changed dist files

* Revert "Added changed dist files"

This reverts commit dbda25a228.

* Changed function name and added the functionaity to src/utils folder

* Added unit test

* Added unit test to /test/util

* Add border thickness and color in DrawRectangle module (#602)

* added border thickness functionality

* add color functionality

* rebuild
2019-01-04 14:05:59 -05:00
MargaretAN9
d104ea744b Update color drop down (#595)
* updated drop down

* fixed greyscale (#593)

* add local to locally stored modules (#596)

* Add drawing rectangles module (#566)

* add drawing rectangle module

* changes

* White balance module (#585)

* white baalance module

* improved algorithm

* limit check

* Ability to set background color when "over cropping" to enlarge canvas (#563)

* ability to set background color when over cropping to enlarge canvas

* changes

* Clarify that saved sequence will only be available in this browser (#587)

* clarify that saved sequence will only be available in this browser

* changes

* changes

* changes

* Added a function to sequencer and then made the functionality available to crop and overlay module. (#592)

* Add manifest.json and cache static assets for offline use (#331)

* Add manifest.json

* cache static assets for offline use

* update cache

* add meta theme-color and change static files to be cache

* cache the files on network request

* caching on first run

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add a button to clear cache

* add styling to clear cache link

* Update Modules.js (#452)

I've arranged the modules in alphabetical order.

* Added a function to parse Input coordinates and added the functionality for crop and overlay modules

* Added changed dist files

* Revert "Added changed dist files"

This reverts commit dbda25a228.

* Changed function name and added the functionaity to src/utils folder

* Added unit test

* Added unit test to /test/util

* Add border thickness and color in DrawRectangle module (#602)

* added border thickness functionality

* add color functionality
2019-01-04 12:34:13 -05:00
dependabot[bot]
bc122af258 Bump jsqr from 0.2.2 to 1.1.1 (#532)
Bumps [jsqr](https://github.com/cozmo/jsQR) from 0.2.2 to 1.1.1.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-04 12:21:51 -05:00
dependabot[bot]
11476d5084 Bump looks-same from 4.1.0 to 5.0.1 (#559)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 4.1.0 to 5.0.1.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v4.1.0...v5.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-04 12:20:49 -05:00
dependabot[bot]
a2157be2da Bump tape from 4.9.1 to 4.9.2 (#579)
Bumps [tape](https://github.com/substack/tape) from 4.9.1 to 4.9.2.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v4.9.1...v4.9.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-04 12:19:50 -05:00
Mridul97
b71e9dec12 Add border thickness and color in DrawRectangle module (#602)
* added border thickness functionality

* add color functionality
2019-01-04 11:27:29 -05:00
Slytherin
aad1f823d3 Added a function to sequencer and then made the functionality available to crop and overlay module. (#592)
* Add manifest.json and cache static assets for offline use (#331)

* Add manifest.json

* cache static assets for offline use

* update cache

* add meta theme-color and change static files to be cache

* cache the files on network request

* caching on first run

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add a button to clear cache

* add styling to clear cache link

* Update Modules.js (#452)

I've arranged the modules in alphabetical order.

* Added a function to parse Input coordinates and added the functionality for crop and overlay modules

* Added changed dist files

* Revert "Added changed dist files"

This reverts commit dbda25a228.

* Changed function name and added the functionaity to src/utils folder

* Added unit test

* Added unit test to /test/util
2019-01-04 11:27:00 -05:00
Mridul97
b520622bfd Clarify that saved sequence will only be available in this browser (#587)
* clarify that saved sequence will only be available in this browser

* changes

* changes

* changes
2019-01-03 16:22:21 -05:00
Mridul97
6028520197 Ability to set background color when "over cropping" to enlarge canvas (#563)
* ability to set background color when over cropping to enlarge canvas

* changes
2019-01-03 15:00:11 -05:00
Vibhor Gupta
a60acd5a72 White balance module (#585)
* white baalance module

* improved algorithm

* limit check
2019-01-03 14:26:06 -05:00
Mridul97
0fc8007e79 Add drawing rectangles module (#566)
* add drawing rectangle module

* changes
2019-01-03 13:41:34 -05:00
Mridul97
5bdaea3688 add local to locally stored modules (#596) 2019-01-03 12:23:16 -05:00
MargaretAN9
e353465dce fixed greyscale (#593) 2019-01-03 00:39:31 -05:00
Vibhor Gupta
39c70d1304 updating description text to default (#574) 2019-01-02 19:06:20 -05:00
HarshKhandeparkar
611016b022 Fixed Gif Generation (#561)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* Fix Gif
2018-12-28 22:10:02 +05:30
Varun Gupta
f77cface7b Merge pull request #560 from tech4GT/updateDist2
update dist
2018-12-27 12:33:34 +05:30
tech4GT
f3291e201f update dist
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-27 12:32:34 +05:30
Varun Gupta
901cf6a96c Merge pull request #555 from Divy123/docs-improve
Added documentation for all remaining modules
2018-12-27 12:30:38 +05:30
divy123
7f4f9a0950 Added dist file changes 2018-12-26 22:36:24 +05:30
divy123
3a39d2b4bb Merge remote-tracking branch 'upstream/main' into docs-improve 2018-12-26 22:05:02 +05:30
Slytherin
3ab02125cb Fixed a typo. 2018-12-26 20:25:30 +05:30
Varun Gupta
d5aac98a29 Merge pull request #554 from HarshKhandeparkar/btn-rearrange
Rearrange Sequence Buttons
2018-12-26 19:49:06 +05:30
divy123
8ff09e26cc Corrected markdown format-2 2018-12-26 00:33:30 +05:30
divy123
d7b175eceb Corrected markdown format 2018-12-26 00:26:14 +05:30
divy123
ee5a3a5e4f Added index to MODULES.md 2018-12-26 00:21:19 +05:30
divy123
35b95a68b1 Added documentation for all modules in Modules.md and added a link in info.json of each Module 2018-12-25 03:59:39 +05:30
HarshKhandeparkar
5288973a48 cleanup 2018-12-23 17:27:58 +05:30
HarshKhandeparkar
d49acd504e btn-fix 2018-12-23 17:26:06 +05:30
HarshKhandeparkar
ac9086e4ef rearrange buttons 2018-12-21 00:17:28 +05:30
Varun Gupta
94e4dfe1b9 Merge pull request #553 from tech4GT/deadLink
fix contributing.md
2018-12-20 08:51:48 +05:30
tech4GT
056e57af8b fix contributing.md
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-20 08:50:30 +05:30
Varun Gupta
9fedf4b9c7 Merge pull request #552 from tech4GT/dependencies
Update dist files
2018-12-19 17:20:04 +05:30
tech4GT
300d972718 update dist files
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-19 17:17:57 +05:30
Varun Gupta
e2f1fb9729 Merge pull request #548 from publiclab/dependabot/npm_and_yarn/tape-run-5.0.0
Bump tape-run from 4.0.0 to 5.0.0
2018-12-19 17:16:57 +05:30
Varun Gupta
3e5cec32e4 Merge pull request #549 from aashna27/Take-Photo-functionality
TakePhoto functionality added
2018-12-19 17:12:09 +05:30
tech4GT
8a96bd8cac update dist files
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-19 17:04:09 +05:30
tech4GT
7cd89c4481 Merge branch 'main' of https://github.com/publiclab/image-sequencer into local 2018-12-19 17:01:45 +05:30
Varun Gupta
980966ecfa Merge pull request #551 from tech4GT/fixInsertStep
fix bug preventing insert-step
2018-12-19 17:01:17 +05:30
tech4GT
eebf149532 fix bug preventing insert-step
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-19 17:00:09 +05:30
aashna27
59898d72fe TakePhoto functionality added 2018-12-18 02:43:28 +05:30
Varun Gupta
23f4851bb5 Merge pull request #545 from Divy123/add-step-btn
Added insert step button at every step
2018-12-17 16:34:57 +05:30
divy123
6bab70ad09 Add step butoon disabled for last step 2018-12-17 16:02:32 +05:30
tech4GT
327b421284 remove excess logs
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-17 11:54:25 +05:30
tech4GT
98e4eca24f update sequence expansion
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-17 11:50:16 +05:30
dependabot[bot]
a93440093b Bump tape-run from 4.0.0 to 5.0.0
Bumps [tape-run](https://github.com/juliangruber/tape-run) from 4.0.0 to 5.0.0.
- [Release notes](https://github.com/juliangruber/tape-run/releases)
- [Changelog](https://github.com/juliangruber/tape-run/blob/master/History.md)
- [Commits](https://github.com/juliangruber/tape-run/compare/v4.0.0...v5.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-17 06:12:30 +00:00
tech4GT
0c2d2a47d8 fix save-sequence and refactor
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-17 10:56:17 +05:30
tech4GT
16debae154 fixes #544 and final changes
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-16 20:01:53 +05:30
tech4GT
3e30c0f7ed Merge branch 'add-step-btn' of https://github.com/Divy123/image-sequencer into divy 2018-12-16 16:32:07 +05:30
divy123
fd78285ac7 Merge branch 'add-step-btn' of https://github.com/Divy123/image-sequencer into add-step-btn 2018-12-16 16:03:56 +05:30
divy123
4eb386eb47 Added font-awesome icon and added colors to it 2018-12-16 16:02:49 +05:30
divy123
f27b09793c Changed arrow functions to normal functions 2018-12-16 15:39:48 +05:30
dependabot[bot]
a56e8a3b16 Bump buffer from 5.0.8 to 5.2.1 (#524)
Bumps [buffer](https://github.com/feross/buffer) from 5.0.8 to 5.2.1.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v5.0.8...v5.2.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-15 19:14:39 -05:00
dependabot[bot]
b666ad510b [Security] Bump bootstrap from 3.3.7 to 3.4.0 (#543)
Bumps [bootstrap](https://github.com/twbs/bootstrap) from 3.3.7 to 3.4.0. **This update includes security fixes.**
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v3.3.7...v3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-15 18:58:45 -05:00
dependabot[bot]
809fb0b37a [Security] Bump cached-path-relative from 1.0.1 to 1.0.2 (#519)
Bumps [cached-path-relative](https://github.com/ashaffer/cached-path-relative) from 1.0.1 to 1.0.2. **This update includes security fixes.**
- [Release notes](https://github.com/ashaffer/cached-path-relative/releases)
- [Changelog](https://github.com/ashaffer/cached-path-relative/blob/master/History.md)
- [Commits](https://github.com/ashaffer/cached-path-relative/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-15 18:58:08 -05:00
Slytherin
a4818d70d8 Merge branch 'main' into add-step-btn 2018-12-16 02:25:12 +05:30
divy123
537cc41b36 Added insert step button at every step 2018-12-16 02:16:45 +05:30
Jonathan Xu
95f8dad901 Add grid of thumbnails (#539)
* Added four preview images

* Added preview images to buttons

* Maked the crop preview resposive

* icon overlays

* made previews square

* finalized css for square images

* Added four preview images

* Added preview images to buttons

* Maked the crop preview resposive

* icon overlays

* made previews square

* finalized css for square images
2018-12-09 22:35:32 -05:00
Varun Gupta
ceca433806 Merge pull request #536 from tech4GT/update
Update dist and lock files
2018-12-07 23:37:09 +05:30
tech4GT
1e719936c4 update dist and lock files
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-12-07 23:31:01 +05:30
pomyo
1ae20b536a Update defaultHtmlStepUi.js (#517) 2018-12-07 12:52:48 -05:00
Osama Mostafa
753e73f355 Update README.md (#525)
Updated the command for installing dependencies for Unix based platform to:
`sudo npm run setup` instead of  `sudo npm setup` as requested in issues.
2018-12-07 12:41:59 -05:00
dependabot[bot]
a26a441b20 Bump browserify from 13.0.0 to 16.2.3 (#533)
Bumps [browserify](https://github.com/browserify/browserify) from 13.0.0 to 16.2.3.
- [Release notes](https://github.com/browserify/browserify/releases)
- [Changelog](https://github.com/browserify/browserify/blob/master/changelog.markdown)
- [Commits](https://github.com/browserify/browserify/compare/13.0.0...v16.2.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 21:12:01 -05:00
dependabot[bot]
7ae8a2ddf7 Bump bootstrap from 3.2.0 to 3.3.7 (#523)
Bumps [bootstrap](https://github.com/twbs/bootstrap) from 3.2.0 to 3.3.7.
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v3.2.0...v3.3.7)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 21:11:48 -05:00
dependabot[bot]
c81f5c6caf Bump looks-same from 3.3.0 to 4.1.0 (#531)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 3.3.0 to 4.1.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v3.3.0...v4.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 16:20:32 -05:00
dependabot[bot]
6d381c0df8 Bump font-awesome from 4.5.0 to 4.7.0 (#527)
Bumps [font-awesome](https://github.com/FortAwesome/Font-Awesome) from 4.5.0 to 4.7.0.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/compare/v4.5.0...v4.7.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 16:20:09 -05:00
dependabot[bot]
6a2f106b4c Bump image-filter-core from 1.0.0 to 2.0.2 (#528)
Bumps [image-filter-core](https://github.com/canastro/image-filter-core) from 1.0.0 to 2.0.2.
- [Release notes](https://github.com/canastro/image-filter-core/releases)
- [Commits](https://github.com/canastro/image-filter-core/commits/2.0.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 16:14:57 -05:00
dependabot[bot]
65a6b77b78 Bump grunt-contrib-concat from 0.5.1 to 1.0.1 (#522)
Bumps [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) from 0.5.1 to 1.0.1.
- [Release notes](https://github.com/gruntjs/grunt-contrib-concat/releases)
- [Changelog](https://github.com/gruntjs/grunt-contrib-concat/blob/master/CHANGELOG)
- [Commits](https://github.com/gruntjs/grunt-contrib-concat/compare/v0.5.1...v1.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-05 18:42:04 -05:00
dependabot[bot]
c688817ffc Bump image-filter-threshold from 1.0.0 to 2.0.1 (#521)
Bumps [image-filter-threshold](https://github.com/canastro/image-filter-threshold) from 1.0.0 to 2.0.1.
- [Release notes](https://github.com/canastro/image-filter-threshold/releases)
- [Commits](https://github.com/canastro/image-filter-threshold/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-05 18:41:54 -05:00
dependabot[bot]
ca67bf1ece Bump ora from 2.1.0 to 3.0.0 (#529)
Bumps [ora](https://github.com/sindresorhus/ora) from 2.1.0 to 3.0.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v2.1.0...v3.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-05 18:41:41 -05:00
dependabot[bot]
88a31e564e Bump tape-run from 3.0.4 to 4.0.0 (#520)
Bumps [tape-run](https://github.com/juliangruber/tape-run) from 3.0.4 to 4.0.0.
- [Release notes](https://github.com/juliangruber/tape-run/releases)
- [Changelog](https://github.com/juliangruber/tape-run/blob/master/History.md)
- [Commits](https://github.com/juliangruber/tape-run/compare/v3.0.4...v4.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-05 11:36:37 -05:00
Bhavay Anand
2161d58e50 slider now goes all the way to right & left (#510) 2018-11-30 18:36:26 -05:00
Oorjit Chowdhary
108e87996a Corrected brightness default view (#509) 2018-11-30 12:50:20 -05:00
Bhavay Anand
f152a78e70 align add-step button with select-module input (#501) 2018-11-30 12:48:21 -05:00
Ville Pajala
5af30d9046 Change button text (#505) 2018-11-29 17:39:28 -05:00
Jan Okoński
ddf4bd0dae Added the sucessfull installation prompt (#485) 2018-11-26 14:06:43 -05:00
Mridul97
3712f0c1cf Skip writing defaults (#497)
* skip writing defaults

* solve build errors
2018-11-26 14:06:13 -05:00
Jonathan Xu
f672dc814a display add step menu with common modules as "quick" buttons (#479)
* added icons, rearranging

* basic framework for addstep modules

* linked buttons to automatic step addition

* Delete package-lock.json

* rounded buttons and text movement in image sequencer select

* made null option visible in select dropdown

* package-lock.json
2018-11-21 19:49:48 -05:00
Jeffrey Warren
98c71b18a8 Add manifest.json and cache static assets for offline use (#331) (#486)
* Add manifest.json

* cache static assets for offline use

* update cache

* add meta theme-color and change static files to be cache

* cache the files on network request

* caching on first run

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add a button to clear cache

* add styling to clear cache link
2018-11-20 22:53:38 -05:00
Bhavay Anand
3ca4081042 fixed few typos (#482)
* fixed few typos

* fixed typos in docs

* suggested changes
2018-11-20 18:04:34 -05:00
HarshKhandeparkar
cd6f61d71a Flash Message bug fix (#481) 2018-11-20 17:04:09 -05:00
HarshKhandeparkar
20cf3277ea Feature enter to save (#483)
* Flash Message bug fix

* enter-to-submit functionality added

* cleanup
2018-11-20 16:46:07 -05:00
HarshKhandeparkar
bf13d5807a GCI task pull request (#474)
* GCI task commit

* GCI task commit

* Cleaned up the code

* Added the css to demo.css file

* Final cleanup and shortened code

* Code compacting

* All beautify changes reverted

* Spacing corrected
2018-11-18 12:29:19 -05:00
Rishabh Rawat
ef10fb77f1 Capitalize the Gif text on View Gif button. (#476) 2018-11-17 23:17:22 -05:00
Jeffrey Warren
19110c4677 Colormap fixes! (#475)
* updated colormap.js

* remove redundancy

* compile

* added maps to interface
2018-11-17 11:19:58 -05:00
Jan Okoński
d209cd46b1 Added a success message after a successfull sequence saving (#469) 2018-11-13 14:35:57 -05:00
Mridul97
4bdc5b6583 Add contrast module (#463) 2018-11-13 12:22:48 -05:00
Slytherin
4576e497db Disabled save-sequence button when no steps are added (#462) 2018-11-11 14:41:55 -05:00
kevinzluo
1311119787 Alphabetizes the modules in src/Modules.js (#441) 2018-11-11 13:12:56 -05:00
aashna27
9e1a12c58d brightness module's info.json modified (#461) 2018-11-11 12:51:09 -05:00
aashna27
948f67fb60 rebuild (#454) 2018-11-08 15:44:36 -05:00
Jeffrey Warren
8685dcb66c bugfixes (#457) 2018-11-08 14:22:25 -05:00
Jeffrey Warren
2243a4b8f7 Update README.md 2018-11-08 10:46:12 -05:00
Jeffrey Warren
7fe16735b3 Update README.md 2018-11-05 12:19:37 -05:00
Jeffrey Warren
a17d1a6ccd ability to set image via url hash (#455) 2018-11-05 12:10:20 -05:00
KusioDev
5f57123503 Add resize module (#451)
* added resize module - without test

* Added resize test, deleted unused value in blend test (which I've added before)

* Fixed test

* Fixed test

* added modules file

* added imagejs to package

* removed test - not able to check width and height of the element

* Changed resize calculations
2018-11-03 00:39:41 -04:00
Varun Gupta
d2ff6f2d6c add demo files to npmignore (#425)
* add demo files to npmignore

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>

* remove dist and test from npmignore
2018-10-30 20:14:10 -04:00
TheRealBilaal
361be0074c Added cli installation message (#448)
* Added cli installation message (#338)

* Added cli installation message (#338)
2018-10-30 19:16:47 -04:00
Sparks
f9376808fd Include a back-to-top Button on scrolling down (#446)
* Update index.html

* Create scrollToTop.js

* Update demo.css

* Update index.html
2018-10-27 18:34:21 -04:00
faithngetich
85c92626e4 Create config.yml (#404)
* Create config.yml

* Update the link where the code will be published 

Co-Authored-By: faithngetich <faithngetich188@gmail.com>
2018-10-27 18:30:28 -04:00
Timofey Barinov
b30b539dab Added gif download modal (#442)
* Enhance gif view

* Gif modal download button & Fix gif downloading

* Fix gif generation aspect ratio

* Fix fix gif downloading

* Clarified Download(PNG) button
2018-10-26 13:53:49 -04:00
KusioDev
e5e372d89d Add configurable parameter for blend module to chose image (#424)
* Add configurable parameter for blend module to chose image

* Made minor changes

* Edit test to work with new parameter

* blend offset test added

* blend offset test added

* fixed blend offset test
2018-10-23 15:03:41 -04:00
aashna27
11b65604cd Added slider for Brightness and Blur modules (#428) 2018-10-22 17:01:12 -04:00
Sasha Boginsky
c762f1ad5d Add issue and pull request templates into image sequencer repository (#420)
* Add issue and pull request templates into image sequencer repository

* Add issue and pull request templates into image sequencer repository
2018-10-22 15:09:25 -04:00
aashna27
965399a2b4 Added scripts in package.json to fix installation (#411)
* Added scripts in package.json to fix installation

* Update setup script

* Update README.md

Add installation instructions for windows

* Update README.md

added headers for windows and Unix
2018-10-22 11:55:18 -04:00
aashna27
3df5ca3802 Added link in description of edge-detect module (#419) 2018-10-22 11:54:39 -04:00
Jeffrey Warren
7e594c4168 updated package.json versions (#426) 2018-10-20 18:40:32 -04:00
Kshitij
5e28f901eb fix typos (#412)
* fix typos

This commit fixes the issue #408

* remove trailing space
2018-10-20 02:37:14 +08:00
sagarwala
48eafe806f removed typos as mentioned in issue #408 (#410) 2018-10-17 09:32:20 +08:00
Sasha Boginsky
6638e9bdb4 Update info.json #407 (#413)
* Update info.json

* Update PRs #413
2018-10-16 12:16:56 +08:00
Varun Gupta
bf80c2b2b6 add lock files (#414)
Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>
2018-10-16 12:12:11 +08:00
Varun Gupta
e512e98921 update start script (#406)
Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>
2018-10-14 06:22:19 +08:00
puneet bindal
9168c15cf9 added gif feature (#360)
* added gif feature

* increased frame duration n changed gif btn name

* removed inline css

* improved ui

* #363 Add placeholder option to input (#370)

* Add placeholder option to input , change type of brightness input to number

 Changes to be committed:
	modified:   examples/lib/defaultHtmlStepUi.js
	modified:   src/modules/Brightness/info.json

* change 0% to 0 in brightness placeholder

* Add gamma module (#374)

* Add gamma module

* update description

* Add matrix math module (#358)

* Add matrix math module

* add info.json file

* correct format of module

* Add a constant factor input field

* clone the pixels array

* change default values

* add extra information on convolution module (#381)

* adds default values to input fields for all module steps ( fixes #382 ) (#384)

* added default values to input fields for all module steps

* merged

Signed-off-by: Ankit Singla <asingla590@gmail.com>

* Accept type images in input field #364 (#366)

* gif button name changed

* fixes #383 (#396)

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>

* fix (#387)

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>

* updated

* Issue #392 Fixes alignment of message in Add step box (#393)

*  Fixes alignment of message in Add step box

* fixes css info id

* updates class selector in demo

* Spacing changes

* correctly regulates the behaviour of all links (#397)

Signed-off-by: Ankit Singla <asingla590@gmail.com>

* enables Save button for an action if any of its input fields gain focus (#394)

* Updated index.html (#379)

* add histogram module (#354)

* add histogram module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add option to drop gradient

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>

* fix bug

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>
2018-10-10 03:46:04 -05:00
Varun Gupta
276a637ac3 add histogram module (#354)
* add histogram module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add option to drop gradient

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>

* fix bug

Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>
2018-10-08 14:56:35 -05:00
Daksh Gondaliya
1d085c7f20 Updated index.html (#379) 2018-10-08 14:14:02 -04:00
Ankit Singla
802b281096 enables Save button for an action if any of its input fields gain focus (#394) 2018-10-08 14:13:09 -04:00
Ankit Singla
67408ca338 correctly regulates the behaviour of all links (#397)
Signed-off-by: Ankit Singla <asingla590@gmail.com>
2018-10-08 14:12:34 -04:00
Daniel Larner
a67fe91d0d Issue #392 Fixes alignment of message in Add step box (#393)
*  Fixes alignment of message in Add step box

* fixes css info id

* updates class selector in demo

* Spacing changes
2018-10-08 12:22:56 -04:00
Varun Gupta
09669fe858 fix (#387)
Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>
2018-10-06 13:06:41 -04:00
Varun Gupta
768117a078 fixes #383 (#396)
Signed-off-by: Varun Gupta <varun.gupta1798@gmail.com>
2018-10-06 13:06:15 -04:00
aashna27
2e7e042baa Accept type images in input field #364 (#366) 2018-10-05 13:18:56 -04:00
Ankit Singla
b300dc2d1f adds default values to input fields for all module steps ( fixes #382 ) (#384)
* added default values to input fields for all module steps

* merged

Signed-off-by: Ankit Singla <asingla590@gmail.com>
2018-10-05 11:55:11 -04:00
Mridul97
fef021911b add extra information on convolution module (#381) 2018-10-05 08:00:05 -04:00
Mridul97
70654a5aac Add matrix math module (#358)
* Add matrix math module

* add info.json file

* correct format of module

* Add a constant factor input field

* clone the pixels array

* change default values
2018-10-04 12:46:21 -04:00
Mridul97
338e610fe7 Add gamma module (#374)
* Add gamma module

* update description
2018-10-03 15:00:42 -04:00
Adriano Costa
06d2aaf1e2 #363 Add placeholder option to input (#370)
* Add placeholder option to input , change type of brightness input to number

 Changes to be committed:
	modified:   examples/lib/defaultHtmlStepUi.js
	modified:   src/modules/Brightness/info.json

* change 0% to 0 in brightness placeholder
2018-10-02 18:18:31 -04:00
vikul1234
5a362f5c9a Update demo.css (#365) 2018-10-01 11:46:57 -06:00
puneet bindal
76826d431d refracted defaultHtmlStepUi.js (#362) 2018-09-30 19:43:51 -06:00
Mridul97
88364decf6 change display value of ndvi from 0-255 to -1 to 1 (#333)
* change display value of ndvi from 0-255 to -1 to 1

* change in dist files

* Truncate ndvi value for displaying
2018-09-12 11:10:32 -04:00
Mridul97
bb17e9452f Add download button (#328) 2018-09-11 15:57:55 -04:00
Varun Gupta
cce65141d2 fix UI functions (#330)
* fix UI functions

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* Update package.json
2018-09-08 11:13:25 -04:00
Mridul97
b707592588 Show 'Press save to see changes' next to each step's 'Save' button (#329) 2018-09-05 18:17:28 -04:00
Varun Gupta
0638a1c68c refactor and remove hysteresis (#327)
* refactor and remove hysteresis

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixes #323

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* bump version #
2018-09-05 16:39:13 -04:00
Mridul97
6106e5ee0c Disable-save-button (#322) 2018-08-30 15:04:09 -04:00
Jeffrey Warren
d4eff45664 version bup (#321) 2018-08-06 14:42:19 -04:00
Varun Gupta
5a3b94d4ee fix (#319)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-08-06 14:33:37 -04:00
Varun Gupta
a238fc65e1 2.2.0 (#317) 2018-08-06 12:10:45 -04:00
Varun Gupta
e15e981d0b Colorbar added (#316)
* setup

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* overlay done

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add colorbar fixes #285

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add inputs to colorbar

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-08-06 11:53:08 -04:00
Varun Gupta
43e6253095 change url string fixes #306 (#313)
* change url string fixes #306

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix typo

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-08-04 17:44:09 -04:00
Varun Gupta
6be996692a pixel value on hover in ndvi fixes #307 (#314)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-08-04 11:09:36 -04:00
Varun Gupta
5b4e904636 add toCliString function fixes #140 (#312)
* add toCliString function fixes #140

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-08-04 10:38:41 -04:00
Varun Gupta
5ab018fb84 Meta modules (#308)
* meta-modules in node

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* meta-modules in browser

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* more doc

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix typo

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update docs and sample meta-module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add dynamic modules CLI from npm

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* meta-modules and sequence saving completed

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixed test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-08-04 10:07:20 -04:00
Varun Gupta
10e47656a3 add steps api functions (#293)
* add steps api functions

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* optimize getHeight and getWidth

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-07-25 14:00:54 -04:00
kevinkmmak
56feb4c546 Add-button-dim (#310)
Dim the button onLoad, then enable it when selected.
2018-07-24 12:55:52 -04:00
Varun Gupta
73a9cd2961 named export for single image basic mode fixes #297 (#301)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-07-18 10:39:21 -04:00
Varun Gupta
42d49112ef implement importNewModule (#294)
* implement importNewModule

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* make apis available on input object

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* minor updates and more docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* major refactor simplify module loading

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* final updates and invert installed from npm

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update contributing.md

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update documentation

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-07-18 10:14:16 -04:00
Varun Gupta
0c0147354e fallback to jpg when no format detected (#296)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-07-01 08:09:10 -04:00
Varun Gupta
510cf3421a reduce redundance of add and insert fixes #261 (#295)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-21 15:15:09 -04:00
Varun Gupta
8d6b82d988 Minimize mod req (#289)
* remove trailing spaces from Run.js

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* minimize module requirements demonstrated with invert fixes #122

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactored modules

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* remove all trailing spaces from all files

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixing crop module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update contributing.md

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-15 14:44:18 -05:00
Varun Gupta
5132612dc2 fixed the demo (#291)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-11 11:25:33 -04:00
Varun Gupta
f4315159a9 fix remove step UI (#288)
* fix remove step UI

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* 2.1.0
2018-06-08 15:46:32 -04:00
Varun Gupta
de20254637 2.0.0 (#287) 2018-06-08 14:31:50 -04:00
Varun Gupta
10c6ad5865 Run optimize (#275)
* fixes #269

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update demo

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactor and comments

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update readme

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* updated and refactored

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update readme

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* trying to fix tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update documentation

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update to config.mode = test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* finaly everything works

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* 1.8.0

* update test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add test for run

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-08 14:13:41 -04:00
Varun Gupta
a0f7e6c766 add importString and refactor (#283)
* add importString and refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update tests and minor changes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update importImage

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-06 21:21:53 -04:00
Varun Gupta
2b07ecdb36 Fix import image (#282)
* fix default image path

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix importImage to take proper input

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-06 20:03:50 -04:00
Jeffrey Warren
37122d4c28 test import string with no configs (#279)
* test import string with no configs

* now working without ()

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactor for readability

* refactor for pipes | between multiple step settings

* fixed bugs

* test fixed
2018-06-03 13:22:40 -07:00
Varun Gupta
871453b857 Url params 🎉 (#276)
* basic implementation

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix bug

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix everything

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add test and refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update demo

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix comma issue

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* now doing with native encode

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-03 09:11:07 -07:00
Varun Gupta
ac183205f0 implement basic toString() (#272)
* implement basic toString()

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* remove load-image from string

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* more refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* doing es5 way

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* final refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* remove if else from map

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix function call

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add sequencer.steps

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add tests for toString and stepToString

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix toString final

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix build failing

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactored and fix tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* refactor tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-06-01 12:45:22 -04:00
Varun Gupta
be810fb9c4 add basic test and remove some bugs (#271)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-28 20:54:23 -04:00
Varun Gupta
8d3ca0887f fixes #267 dragZone listener getting confused (#270)
* fixes #267 dragZone listener getting confused

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* remove log

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-28 18:44:42 -04:00
Varun Gupta
1de72d7325 Prev step final API (#268)
* 1.7.0

* fix the api

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixes #266

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* finally got this to work! Phew :D

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* remove extra log

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* getStepAPI in insertStep

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add getPreviousStep API

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* more api

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* changes and refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* now using this.getStep and related functions

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add getNextStep

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* minor refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update getIndex

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-28 01:33:17 -04:00
Varun Gupta
58a4798674 ImportImage (#264)
* not working yet...

* fixed basic functioning!

* working! now on to blending
2018-05-24 17:18:48 -04:00
Varun Gupta
f8006da07e Blend module updated (#263)
* blend initial steps

* access to prior steps via passed util api

* Update Blend And add missing start script

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* blend complete

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-24 16:01:09 -04:00
Varun Gupta
09c4f250a2 add API to get steps (#259)
* add API to get steps

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update dist and refactor

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* rename to getStepOutput

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* api complete

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add test

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* change indentation to 2 spaces

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* minor fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* new API

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* remove commented code

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* modifiication to invert

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-23 17:38:20 -07:00
Varun Gupta
bd490d2515 add serve grunt task (#258)
* add serve grunt task

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add npm start

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* update readme

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix typo

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-22 10:56:46 -07:00
Varun Gupta
ca79924d11 fixes #254 (#257)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-05-22 03:04:14 -07:00
Jeffrey Warren
630eb773de start breaking out a ui feature to set an input step (#253)
* start

* refactoring

* working

* version bump
2018-05-09 13:49:11 -04:00
Jeffrey Warren
6ce78f87f4 ui output for average (#252) 2018-05-09 10:11:20 -04:00
Jeffrey Warren
991e9bb29c start to average module (#249)
* start to average module

* completed average module

* added average module, version bump
2018-05-09 09:39:33 -04:00
Jeffrey Warren
cbbfbff4bc bugfix version bump (#248) 2018-05-07 10:46:38 -04:00
Jeffrey Warren
768e2ce95d Ui refactor and drag to crop (#245)
* Drag to crop rebase step (#244)

* 1.1.0

* 1.2.0

* added plugin

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* drag to crop enabled

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* improvement

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* done dragToCrop

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* done with updated ui

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* solved bug for multiple consecutive crops

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixed and updated

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* externalized image area select code

* major refactoring of crop drag and demo ui modules

* work on crop module and ui refactor

* completed Step drag ui refactor

* revert unbuilt to rebase

* built and version bump

* various fixes
2018-05-04 14:27:48 -04:00
Jeffrey Warren
51524f747a uses jquery if available in replace (#240) 2018-05-03 18:02:25 -04:00
Jeffrey Warren
b16b45afa8 removed jquery (#239)
* removed jquery

* version bump
2018-05-03 17:33:01 -04:00
Jeffrey Warren
39418da187 Format detection fix (#238)
* better format detection

* version
2018-05-03 16:35:02 -04:00
Jeffrey Warren
8547c60873 Update PixelManipulation.js (#236) 2018-05-02 17:09:09 -04:00
Jeffrey Warren
adc21ae843 Rename colormap (#235) 2018-05-02 16:08:50 -04:00
Jeffrey Warren
2abf0fae09 Code cleanup, re-organizing and tidying (#226)
* initial cleanup

* build

* additions and build
2018-04-29 12:16:11 -04:00
Jeffrey Warren
711ae62ee3 simplified demo ui (#224)
* simplified demo ui

* show description

* smaller, labelled example image
2018-04-28 18:40:34 -04:00
Jeffrey Warren
4d75fb9640 Infos updated for new title/description format (#221)
* initial work

* working with failing test

* info modules

* compiled

* rework of CONTRIBUTING
2018-04-24 17:15:27 -04:00
Marzanna
5ac3ef008d demo images can be downloaded by clicking (#220)
* demo images can be downloaded by clicking

* modified download to extract image type from url

* refactored image output into standalone function

* updated to call fileExtension function
2018-04-20 19:56:32 -04:00
Varun Gupta
98f913b32e Material icon (#217)
* add pwa icon

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* icon working

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-04-20 14:07:52 -04:00
Jeffrey Warren
c2756ffdbb Module info.json -based demo UI (WIP) (#219)
* initial work

* working with failing test

* now should pass test
2018-04-20 09:34:08 -04:00
Varun Gupta
d887f5eb61 Update version (#208)
* 1.1.0

* 1.2.0

* check in dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-04-09 16:53:40 -04:00
Varun Gupta
3b791ad58b add loading spinner fallback (#202)
* add loading spinner fallback fixes #189

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* handle testing with progress spinners

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* apply fixes and improvements

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add example

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* bug fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* resolves #189

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-03-31 01:21:28 -04:00
Varun Gupta
fba80bb151 Dynamic fix as fun (#207)
getNeighborPixel(x, y) method for Dynamic module
2018-03-30 17:41:30 -04:00
Varun Gupta
0ceb36ffde 1.1.0 (#206) 2018-03-24 10:06:50 -04:00
Jeffrey Warren
edaa8895c7 Update info.json with NDVI description (#199)
* Update info.json

* compiled
2018-03-12 13:13:43 -04:00
Raounak Sharma
efd5bf7624 Changed the warning log (#195)
Since our execution is not exactly async, hence the corresponding change in
the log message is more suitable log.

close 194
2018-03-09 17:14:03 -05:00
Jeffrey Warren
96143564fa Update index.html 2018-03-01 13:39:29 -06:00
Gayathri
973ec6d6e4 Added how to run the debug script (#192) 2018-02-26 10:53:39 -05:00
Danielle Shwed
801ea35393 Add Saturation Module (#193)
* fixed blur module as well as issue with no output when running debug

* added saturation module

* fixing requested changes

* fixing exportBin

* requested fixes
2018-02-26 10:52:25 -05:00
Varun Gupta
e8ab480687 Added native gaussian Blurring module(no dependencies) (#186)
* Added Blur Module

* Issue 177 fixing Blur module

* blur module fixed info json

* fixing blur module

* Delete .DS_Store

* add a native blurring solution

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixed package.json

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* delete .ds_store and update gitignore

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-22 16:43:14 -05:00
Varun Gupta
9d3e511bca resolves #184 (#185) 2018-02-21 22:10:25 -05:00
mayank1010
d3a4c336a0 Empty directory bug fixed (#179)
added the check to test if the directory is empty by comparing it's length with 0.
2018-02-21 14:55:24 -05:00
Varun Gupta
0fd797ed5a resolves #182 (#183)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-21 11:31:20 -05:00
Varun Gupta
27ee18b3d2 resolves #153 (#180)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-20 17:28:19 -05:00
Varun Gupta
5922b0de58 resolves #174 (#175)
Update readme -- resolves #174
2018-02-16 18:36:21 -05:00
Varun Gupta
fd45d3caf3 resolves #132 fix options object (#171)
* resolves #132 fix options object

* Add Documentation for --details parameter

* fix spacing issue

* update naming of options parameter

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-16 18:03:39 -05:00
Varun Gupta
bbef4bca57 Added Edge Detection module (#168)
* step 1 grayscale

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add basic edge detection resolves #166

* updated the description

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixed typo

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* updated the description for edge detection module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add NonMaxSuppression and DoubleThreshold

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* comlpeted edge detection

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* cleared remaining weak edges

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-16 17:07:00 -05:00
Varun Gupta
32c5a29906 resolves #131 create output directory immediately (#167)
* resolves #131 create output directory immediately

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix error if no steps are passed

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add exit message if steps not passed

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add test for creating output directory
2018-02-06 16:42:22 -05:00
Varun Gupta
c5dee8aef3 Add bookmarklet (#164)
* resolves #162

* add bookmarklet link to readme resolves #148

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* Update README.md
2018-02-02 12:52:08 -05:00
Varun Gupta
071aa68de7 resolves #162 (#163)
remove module count test - resolves #162
2018-02-01 13:37:58 -05:00
Varun Gupta
87fa166595 Only brightness module (#161)
* fixed package.json

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* resolves #113 add brightness module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-01 12:27:37 -05:00
Varun Gupta
a5d5dd9f52 fixed package.json (#160)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-02-01 11:55:01 -05:00
Rishabh Chaudhary
38accebcc3 Fixed - move module tests into separate test files #141 (#155)
* Fixed -  move module tests into separate test files #141

* Modification

* Restructure, fixed tests
2018-01-29 13:18:15 -05:00
Varun Gupta
c19a663fa2 resolves #133 add -b --basic mode to only output final image update readme (#154)
* resolves #133 add -b --basic mode to only output final image update readme

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* format logs and help

* update dist files
2018-01-23 12:26:02 -05:00
Varun Gupta
38cf05bb9e resolves #129 message to user informing about the async execution (#152)
Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2018-01-21 10:26:37 -05:00
Chinmay Pandhare
3f99e2b44c fixed replaceImage (#151)
* 1.0.0

* Fixed Replace Image

* Added test to check if replaceImage works
2017-10-26 14:35:23 -04:00
Jeffrey Warren
73e5d14569 various tweaks and adjustments to demo; bugfix for select/input changes (#149) 2017-10-23 23:16:22 -04:00
Chinmay Pandhare
135c142ba8 Updates to Demo (#143)
* 1.0.0

* Added 'select' input

* Added loader

* Fix File Reader
2017-10-18 17:02:42 -04:00
Jeffrey Warren
14c59be19c Additions to README - diagrams (#144)
* Additions to README

* Update README.md

* Add files via upload
2017-10-18 16:32:33 -04:00
Jeffrey Warren
ec10ab0b0d Update imageSelection.js 2017-10-18 16:28:23 -04:00
Jeffrey Warren
1c7f59cbfd Dynamic module, new demo image, demo cleanup, re-configurable demo steps (#139)
* rebase and build

* bump version to v0.1.1
2017-10-13 21:30:06 -04:00
Jeffrey Warren
bef53ef1a2 Step descriptions (work in progress) (#135)
* additional changes, not sure of yet

* working, but probably redundant code

* remove comment line

* rebuild
2017-10-13 13:16:07 -04:00
Jeffrey Warren
1c7f7c15af assortment of tweaks, additional tests (#134) 2017-10-05 15:16:25 -06:00
makeupsomething
7cbf793655 Added uglify command to build function (#124) 2017-10-05 14:29:46 -06:00
Jeffrey Warren
829e19e58d various fixes and changes to SegmentedColormap module (#128) 2017-10-04 14:31:43 -04:00
Jeffrey Warren
ca6910017d url hash initial implementation (#125)
* url hash initial implementation

* completed url hash UI
2017-10-02 08:37:10 -04:00
Jeffrey Warren
4e780f3a91 drag drop added to demo (#121) 2017-09-11 20:30:50 -04:00
Jeffrey Warren
3a4e4f9575 Merge pull request #117 from publiclab/readme-fixes
Update README.md with fixed Contributing links
2017-09-10 13:11:25 -04:00
Jeffrey Warren
6420a70aad Update CONTRIBUTING.md 2017-09-10 13:11:07 -04:00
Jeffrey Warren
99ec91b916 Update README.md 2017-09-10 12:54:03 -04:00
Chinmay Pandhare
4d9a4bcaa1 Merge pull request #107 from ccpandhare/docs
Update Docs
2017-09-10 03:26:25 +05:30
Jeffrey Warren
0e50a1b2f5 Merge pull request #111 from publiclab/demo-css
Update demo.css for narrower screens
2017-09-09 09:30:33 -04:00
Jeffrey Warren
376c264168 Update demo.css 2017-09-09 09:17:55 -04:00
Jeffrey Warren
1f3000b7f9 Demo styling tweaks (#105)
* html demo tweaks

* in-progress demo styling

* merge fies

* old demo cleanup
2017-09-06 14:34:24 -04:00
Chinmay Pandhare
dc9827049a Merge pull request #109 from ccpandhare/master
Remove const
2017-09-05 20:39:39 +05:30
Chinmay Pandhare
f69f8461a7 Remove const 2017-09-05 19:45:06 +05:30
Chinmay Pandhare
bde6dbed8f Cleanup CONTRIBUTING.md 2017-09-03 15:58:07 +05:30
Chinmay Pandhare
4fb1ecce86 Added Installation Instructions; Update Dependancies 2017-09-03 15:38:03 +05:30
Chinmay Pandhare
5b860dee83 Merge pull request #104 from ccpandhare/master
Changed const to var
2017-09-01 20:22:17 +05:30
Chinmay Pandhare
959f5db6df Merge master 2017-09-01 20:00:33 +05:30
Chinmay Pandhare
237a96247a Remove ES6 const syntax 2017-09-01 19:59:25 +05:30
Chinmay Pandhare
2e4255a5ca Merge pull request #103 from ROODAY/cli-fixes
Cleaned up CLI
2017-09-01 12:09:33 +05:30
Rudhra Raveendran
fe3ec335fe made CLI cleaner 2017-08-29 10:33:01 -04:00
Chinmay Pandhare
eafc639555 Merge pull request #102 from ROODAY/step-enhancements
Merging Step Enhancements!
2017-08-29 00:25:38 +05:30
Rudhra Raveendran
7da59aed0c Updated README to include CLI instructions 2017-08-28 14:38:26 -04:00
Rudhra Raveendran
d759680869 abstracted validation to a function 2017-08-28 12:51:10 -04:00
Rudhra Raveendran
4c662d908e grammar 2017-08-28 12:16:34 -04:00
Rudhra Raveendran
c5d62e5529 Resolved #97 and #100 2017-08-28 12:14:48 -04:00
Chinmay Pandhare
d466afb90d Merge pull request #95 from ccpandhare/development2
Added Basic CLI
2017-08-26 03:46:14 +05:30
Chinmay Pandhare
72435eb9a4 Merge publiclab:master 2017-08-26 03:29:00 +05:30
Chinmay Pandhare
c7e4ec7c4a Added outputs, fix modulesInfo 2017-08-26 03:27:10 +05:30
Chinmay Pandhare
c28c958414 Merge pull request #94 from ccpandhare/master
Bugfixes
2017-08-24 20:19:03 +05:30
Chinmay Pandhare
38975791ca Basic CLI 2017-08-24 20:13:58 +05:30
Chinmay Pandhare
dbc0ad6e69 Merge from master 2017-08-24 20:07:29 +05:30
Chinmay Pandhare
c3c6713ec1 More Bugfixes 2017-08-24 20:05:57 +05:30
Chinmay Pandhare
873492a456 Binary output can be exported to any directory 2017-08-24 19:35:15 +05:30
Chinmay Pandhare
ca044b1b01 Bugfixes 2017-08-24 19:07:22 +05:30
Chinmay Pandhare
0fa0684076 Merge pull request #92 from ccpandhare/demo
Added Image Sequencer Demo
2017-08-21 21:49:39 +05:30
Chinmay Pandhare
c655b62813 Added output documentation in CONTRIBUTING.md 2017-08-21 10:51:08 +05:30
Chinmay Pandhare
69c656fbd5 Added comments in demo 2017-08-21 10:48:56 +05:30
Chinmay Pandhare
ee467f2a7b Fix build 2017-08-21 10:34:50 +05:30
Chinmay Pandhare
21796bb58c Added output example in demo 2017-08-21 10:11:54 +05:30
Chinmay Pandhare
cc308748c8 Add comments; Remove do-nothing, do-nothing-pix 2017-08-21 10:01:02 +05:30
Chinmay Pandhare
0095462384 Added webgl-distort to list of module candidates 2017-08-20 18:34:04 +05:30
Chinmay Pandhare
54c7393417 Update gitignore 2017-08-20 18:18:18 +05:30
Chinmay Pandhare
555ea9b945 Bootstrap 2017-08-20 18:13:09 +05:30
Chinmay Pandhare
f879f31e4f Merge Demo 2017-08-20 14:28:39 +05:30
Chinmay Pandhare
782e60269e options accessible via step, implemented options in demo 2017-08-15 14:27:38 +05:30
Chinmay Pandhare
963129d513 Updated README and CONTRIBUTING 2017-08-15 08:12:12 +05:30
Chinmay Pandhare
d207c147fe implemented modulesInfo in Demo 2017-08-15 08:02:54 +05:30
Chinmay Pandhare
a9e0068628 modulesinfo browserify fix 2017-08-15 07:16:19 +05:30
Chinmay Pandhare
5b7e47dd79 modules info 2017-08-15 06:56:19 +05:30
Chinmay Pandhare
95ffa0453b Updated Demo 2017-08-14 09:23:33 +05:30
Chinmay Pandhare
76ffb6a013 Implemented addStep, removeStep, loadImage in Demo 2017-08-14 09:22:15 +05:30
Chinmay Pandhare
78fb43a8af Demo 2017-08-13 05:20:02 +05:30
Chinmay Pandhare
04e2ee7903 Added Single Image Demo Markup 2017-08-13 05:12:33 +05:30
Chinmay Pandhare
06af6007a2 Merge branch 'master' of https://github.com/publiclab/image-sequencer into demo 2017-08-13 04:33:25 +05:30
Chinmay Pandhare
42425bcf69 Merge pull request #89 from ccpandhare/testing
Image Diff based testing for PNG images
2017-08-12 09:21:37 +05:30
Chinmay Pandhare
3b73c6d700 Merge pull request #90 from ccpandhare/development2
Added exportBin method
2017-08-10 15:51:07 +05:30
Chinmay Pandhare
889c751399 Built for Browser 2017-08-10 01:03:29 +05:30
Chinmay Pandhare
26538891a3 Added exportBin method 2017-08-10 00:54:58 +05:30
Chinmay Pandhare
1510043a50 Remove image-diff and imagemagick from devDependancies 2017-08-08 15:39:23 +05:30
Chinmay Pandhare
d34130b791 Merge from PublicLab/master 2017-08-08 15:35:07 +05:30
Chinmay Pandhare
8579cfafa7 Image Diff based testing 2017-08-08 15:34:12 +05:30
Chinmay Pandhare
2f117c1f35 imagemagick 2017-08-08 02:09:43 +05:30
Chinmay Pandhare
14b1152e5a Added Demo for FisheyeGl Module (#62)
* demo for FisheyeGl

* demo for FisheyeGl - Bugfixes

* Demo Created

* Demo Created

* Changed Title in Demo

* Improved Demo

* Organize examples directory, Recreate FisheyeGl Demo of fisheyegl using Image Sequencer UI

* Modified tests
2017-08-06 16:41:12 -04:00
Chinmay Pandhare
c90bf3fa0a Merge pull request #88 from ccpandhare/master
Remove lurking tape-test file
2017-08-06 18:06:27 +05:30
Chinmay Pandhare
802648ae69 Remove lurking tape-test file 2017-08-06 17:56:50 +05:30
Chinmay Pandhare
812cd808c7 Made Requested Changes 2017-08-06 17:51:54 +05:30
Chinmay Pandhare
45328999f3 Merge pull request #72 from ccpandhare/modules2
Added DecodeQr Module, Test
2017-08-05 23:10:40 +05:30
Chinmay Pandhare
88f31c9665 Merge from publicab/master 2017-08-05 23:03:32 +05:30
Chinmay Pandhare
235b2428ee imagemagick 2017-08-05 23:00:13 +05:30
Chinmay Pandhare
3354071548 Merge Demo 2017-08-01 23:30:17 +05:30
Chinmay Pandhare
02ec74bad3 Modified tests 2017-08-01 23:24:50 +05:30
Chinmay Pandhare
b8ec24c185 Organize examples directory, Recreate FisheyeGl Demo of fisheyegl using Image Sequencer UI 2017-08-01 23:19:36 +05:30
Chinmay Pandhare
187f66429a Merge Commit 2017-08-01 01:32:58 +05:30
Chinmay Pandhare
8f5e9f0c40 Merge pull request #61 from ccpandhare/modules
Added FisheyeGl Module
2017-07-29 22:30:30 +05:30
Chinmay Pandhare
e6f1ff3243 Resolve Conflicts; Update DecodeQr Module 2017-07-29 04:25:50 +05:30
Chinmay Pandhare
b9797a0329 Merge #86 from publiclab/image-sequencer 2017-07-29 04:13:04 +05:30
Chinmay Pandhare
61bd95355b Use 'fisheyegl' from npm 2017-07-29 04:08:28 +05:30
Chinmay Pandhare
9208216f99 Merge pull request #86 from ccpandhare/development3
Rework UI Handling
2017-07-29 03:56:24 +05:30
Chinmay Pandhare
3421714c2b Merge Commit 2017-07-29 03:50:31 +05:30
Chinmay Pandhare
93941b1280 Updated CONTRIBUTING.md 2017-07-29 03:33:35 +05:30
Chinmay Pandhare
6eea7b8bd6 Updated README.md 2017-07-29 03:31:33 +05:30
Chinmay Pandhare
d1b47a73fe Updated README.md 2017-07-29 03:28:39 +05:30
Chinmay Pandhare
31e9b3ec9d Complete UI Handling 2017-07-29 03:20:17 +05:30
Chinmay Pandhare
1b7dadf41f Merge publiclab/master after #81 2017-07-29 02:58:51 +05:30
Chinmay Pandhare
f1f3574468 Rework UI Handling 2017-07-29 02:53:39 +05:30
Chinmay Pandhare
8610ab1ff8 Merge pull request #81 from ccpandhare/development2
Support External Images
2017-07-29 02:52:50 +05:30
Chinmay Pandhare
2888c2d735 Patch for UI 2017-07-28 18:01:22 +05:30
Chinmay Pandhare
53a8963b72 Build Commit 2017-07-28 12:37:57 +05:30
Chinmay Pandhare
6e136e6c2f Updated README.md 2017-07-28 12:33:23 +05:30
Chinmay Pandhare
467fe1d2e5 Added Unit Test for URL Support 2017-07-28 12:32:29 +05:30
Chinmay Pandhare
b59383ce53 Added URL support for Node.js client 2017-07-28 12:32:04 +05:30
Chinmay Pandhare
b1c9949757 Updated README 2017-07-28 12:07:39 +05:30
Chinmay Pandhare
f3f3f5f615 Merge commit 2017-07-28 12:01:29 +05:30
Chinmay Pandhare
7f17f825ab LoadImages will return nothing, only call a callback 2017-07-28 12:00:30 +05:30
Chinmay Pandhare
ec4459309b Split README (#80)
* Split README

* Added 'Jump to' section in README
2017-07-27 20:26:48 +02:00
jywarren
d80a587bf3 version bump 2017-07-27 14:20:32 -04:00
Chinmay Pandhare
d7eb5a2f0c Update README, Merge Master 2017-07-27 23:44:14 +05:30
Chinmay Pandhare
03d9ff1ea2 Merge pull request #84 from ccpandhare/master
Update main script
2017-07-27 23:35:15 +05:30
Chinmay Pandhare
2e284560e2 Update main script 2017-07-27 23:21:40 +05:30
Chinmay Pandhare
f5c21e7c82 Merge pull request #76 from ccpandhare/testing
Added tests to check support for PNG and GIF
2017-07-27 02:20:44 +05:30
Chinmay Pandhare
fab35c5efb Merge Commit 2017-07-27 01:06:03 +05:30
Chinmay Pandhare
29cb36dd31 BuildFix 2017-07-26 23:26:18 +05:30
Chinmay Pandhare
d90c61f85d Support External Images via Canvas 2017-07-26 23:16:32 +05:30
Chinmay Pandhare
21334ff5d8 Merge pull request #67 from ccpandhare/development
Implemented UI Methods
2017-07-25 02:36:15 +05:30
Chinmay Pandhare
1117279d44 Added a test to check support for PNG and GIF 2017-07-25 01:47:23 +05:30
Chinmay Pandhare
6baed92ec6 Build Completed 2017-07-25 01:11:36 +05:30
Chinmay Pandhare
e9f045f5cd Merge master, Rename this_ and ui: 'none' 2017-07-25 00:59:58 +05:30
Chinmay Pandhare
ec657a6735 Explained imageName in README.md 2017-07-25 00:45:54 +05:30
Chinmay Pandhare
246130c8e6 Merge pull request #73 from lpinca/gh-31
Remove base64-stream dependency and fix #31
2017-07-24 23:56:49 +05:30
Luigi Pinca
82bb274cfb Remove base64-stream dependency
Fixes: https://github.com/publiclab/image-sequencer/issues/31
2017-07-24 16:25:45 +02:00
Chinmay Pandhare
78beae48d9 Added DecodeQr Module, Test 2017-07-23 12:50:22 +05:30
Chinmay Pandhare
7584b1ec45 Added Docs, updated method names 2017-07-23 11:57:05 +05:30
Chinmay Pandhare
cfdc4c509e BuildFix (BugFix) 2017-07-22 02:12:33 +05:30
Chinmay Pandhare
867792927e BuildFix (BugFix) 2017-07-22 02:12:14 +05:30
Chinmay Pandhare
555e37190b Implemented UI Methods 2017-07-22 02:01:03 +05:30
Chinmay Pandhare
a74f67ef06 Built for Browser 2017-07-17 16:00:32 +05:30
Chinmay Pandhare
b963dfd297 Improved Demo 2017-07-17 15:54:56 +05:30
Chinmay Pandhare
10dadeb63b Improved Demo 2017-07-17 15:53:31 +05:30
Chinmay Pandhare
c4c1f5bd2d Improved Demo 2017-07-17 15:15:07 +05:30
Chinmay Pandhare
86d475d3e7 Removed Globals 2017-07-17 15:09:13 +05:30
Chinmay Pandhare
52e8e652c3 Bugfix 2017-07-17 12:07:33 +05:30
Chinmay Pandhare
73930849a7 Merge from Demo 2017-07-17 11:58:51 +05:30
Chinmay Pandhare
dc9b9bcde3 Changed Title in Demo 2017-07-17 11:57:48 +05:30
Chinmay Pandhare
dd595f371c Demo Created 2017-07-17 11:56:08 +05:30
Chinmay Pandhare
1404d455fc Merge from demo 2017-07-17 11:54:31 +05:30
Chinmay Pandhare
5994963253 Merge from demo 2017-07-17 11:54:09 +05:30
Chinmay Pandhare
e6a96d723d Demo Created 2017-07-17 11:51:54 +05:30
Chinmay Pandhare
43d55d2781 demo for FisheyeGl - Bugfixes 2017-07-17 11:23:35 +05:30
Chinmay Pandhare
8d8cf33d23 demo for FisheyeGl 2017-07-16 17:32:35 +05:30
Chinmay Pandhare
09c0a180ec Added Documentation for FisheyeGl 2017-07-16 16:51:28 +05:30
Chinmay Pandhare
51e6c70fc8 Added FisheyeGl Module 2017-07-16 15:39:38 +05:30
Chinmay Pandhare
41c392d838 Merge Master 2017-07-11 12:44:09 +05:30
Chinmay Pandhare
368d11230c Merge ccpandhare:master 2017-07-09 23:48:06 +05:30
Chinmay Pandhare
a4e7470a5e Merge Testing 2017-07-08 20:09:26 +05:30
Chinmay Pandhare
3112816afc Merge testing 2017-07-08 19:38:16 +05:30
Chinmay Pandhare
2eb41b20f9 Merge Commit 2017-07-08 19:13:12 +05:30
Chinmay Pandhare
ec6cc396e4 Merge Commit 2017-07-08 19:12:15 +05:30
jywarren
10dc6c0a7c Merge branch 'master' into gh-pages 2017-03-04 11:22:11 -05:00
jywarren
f6225422b1 Merge branch 'master' into gh-pages 2017-01-09 21:11:39 -05:00
jywarren
5dfbc9d28b Merge branch 'master' into gh-pages 2017-01-09 20:27:10 -05:00
jywarren
74eb686604 Merge branch 'master' into gh-pages 2017-01-09 18:06:50 -05:00
jywarren
fedccd59a1 Merge branch 'master' into gh-pages 2017-01-06 01:39:26 -05:00
jywarren
f1551abb7f .nojekyll file to get gh-pages to see node_modules 2017-01-02 23:59:34 -05:00
jywarren
7c1228fca9 .gitignore for gh-pages 2017-01-02 23:26:54 -05:00
jywarren
1bf58351b4 basic gh-pages deps 2017-01-02 23:19:02 -05:00
275 changed files with 27541 additions and 36998 deletions

11
.codecov.yml Normal file
View File

@@ -0,0 +1,11 @@
comment:
layout: "reach, diff, flags, files"
behavior: default
require_changes: false # if true: only post the comment if coverage changes
require_base: no # [yes :: must have a base report to post]
require_head: yes # [yes :: must have a head report to post]
branches: null # branch names that can post comment
coverage:
status:
project: off
patch: off

35
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,35 @@
### Please describe the problem (or idea)
> What happened just before the problem occurred? Or what problem could this idea solve?
> What did you expect to see that you didn't?
### Please show us where to look
https://beta.sequencer.publiclab.org
### What's your PublicLab.org username?
> This can help us diagnose the issue:
### Browser, version, and operating system
> Many bugs are related to these -- please help us track it down and reproduce what you're seeing!
****
## Thank you!
Your help makes Public Lab better! We *deeply* appreciate your helping refine and improve this site.
To learn how to write really great issues, which increases the chances they'll be resolved, see:
https://publiclab.org/wiki/developers#Contributing+for+non-coders

16
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,16 @@
Fixes #0000 (<=== Replace `0000` with the Issue Number)
Make sure these boxes are checked before your pull request (PR) is ready to be reviewed and merged. Thanks!
* [ ] tests pass -- look for a green checkbox ✔️ a few minutes after opening your PR -- or run tests locally with `npm test`
* [ ] code is in uniquely-named feature branch and has no merge conflicts
* [ ] PR is descriptively titled
* [ ] ask `@publiclab/is-reviewers` for help, in a comment below
> We're happy to help you get this ready -- don't be afraid to ask for help, and **don't be discouraged** if your tests fail at first!
If tests do fail, click on the red `X` to learn why by reading the logs.
Please be sure you've reviewed our contribution guidelines at https://publiclab.org/contributing-to-public-lab-software
Thanks!

25
.github/config.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
# Configuration for welcome - https://github.com/behaviorbot/welcome
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
# Comment to be posted to on first time issues
newIssueWelcomeComment: |
Thanks for opening your first issue here! Please follow the issue template to help us help you 👍🎉😄
If you have screenshots to share demonstrating the issue, that's really helpful! 📸 You can [make a gif](https://www.cockos.com/licecap/) too!
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: |
Thanks for opening this pull request!
There may be some errors, **but don't worry!** We're here to help! 👍🎉😄
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: |
Congrats on merging your first pull request! 🙌🎉⚡️
Your code will be published to https://beta.sequencer.publiclab.org in a day or two.
In the meantime, can you tell us your Twitter handle so we can thank you properly?
Now that you've completed this, you can help someone else take their first step!
See: [Public Lab's coding community!](https://code.publiclab.org)
# It is recommended to include as many gifs and emojis as possible

12
.github/first-timers.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# You can change the labels to suit your needs if "first-timers-only" is not what you are looking for.
# These are some examples.
labels:
- first-timers-only
- help wanted
#If you would like to add your own template for the issue, add an .md file to your .github folder
template: .github/fto-template.md
# You can create the issue in a different repo than where the problem is. Just make sure you installed the bot on the configured repository.
# The issue will link back to the original repository where the contribution will be made.
#repository: repo-name

51
.github/fto-template.md vendored Normal file
View File

@@ -0,0 +1,51 @@
Hi, this is a [first-timers-only issue](https://code.publiclab.org/#r=all). This means we've worked to make it more legible to folks who either **haven't contributed to our codebase before, or even folks who haven't contributed to open source before**.
If that's you, we're interested in helping you take the first step and can answer questions and help you out as you do. Note that we're especially interested in contributions from people from groups underrepresented in free and open source software!
We know that the process of creating a pull request is the biggest barrier for new contributors. This issue is for you 💝
If you have contributed before, **consider leaving this one for someone new**, and looking through our general [help wanted](https://github.com/publiclab/image-sequencer/labels/help-wanted) issues. Thanks!
### 🤔 What you will need to know.
Nothing. This issue is meant to welcome you to Open Source :) We are happy to walk you through the process.
### 📋 Step by Step
- [ ] 🙋 **Claim this issue**: Comment below. If someone else has claimed it, ask if they've opened a pull request already and if they're stuck -- maybe you can help them solve a problem or move it along!
- [ ] 📝 **Update** the file [$FILENAME]($BRANCH_URL) in the `$REPO` repository (press the little pen Icon) and edit the line as shown below.
[See this page](https://code.publiclab.org/#r=all) for some help in taking your first steps!
Below is a "diff" showing in red (and a `-`) which lines to remove, and in green (and a `+`) which lines to add:
```diff
$DIFF
```
- [ ] 💾 **Commit** your changes
- [ ] 🔀 **Start a Pull Request**. There are two ways how you can start a pull request:
1. If you are familiar with the terminal or would like to learn it, [here is a great tutorial](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) on how to send a pull request using the terminal.
2. You can also [edit files directly in your browser](https://help.github.com/articles/editing-files-in-your-repository/) and open a pull request from there.
- [ ] 🏁 **Done** Ask in comments for a review :)
### Please keep us updated
💬⏰ - We encourage contributors to be respectful to the community and provide an update **within a week** of claiming a first-timers-only issue. We're happy to keep it assigned to you as long as you need if you update us with a request for more time or help, but if we don't see any activity a week after you claim it we may reassign it to give someone else a chance. Thank you in advance!
If this happens to you, don't sweat it! Grab another open issue.
### Is someone else already working on this?
🔗- We encourage contributors to link to the original issue in their pull request so all users can easily see if someone's already started on it.
👥- **If someone seems stuck, offer them some help!** Otherwise, [take a look at some other issues you can help with](https://code.publiclab.org/#r=all). Thanks!
### 🤔❓ Questions?
Leave a comment below!

16
.gitignore vendored
View File

@@ -25,6 +25,11 @@ build/Release
# Dependency directory
node_modules
node_modules/*
# Dist Files
dist/*
dist
# Optional npm cache directory
.npm
@@ -32,5 +37,16 @@ node_modules
# Optional REPL history
.node_repl_history
.DS_Store
*.swp
todo.txt
test.js
output.txt
output/
test/core/modules/test_outputs
test/core/modules/test_outputs/*
node_modules/
node_modules/*
test_outputs
/test_outputs

0
.nojekyll Normal file
View File

47
.npmignore Normal file
View File

@@ -0,0 +1,47 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
.DS_Store
*.swp
todo.txt
test.js
output.txt
output/
examples/
icons/
.travis.yml
Gruntfile.js
yarn.lock

View File

@@ -1,16 +1,24 @@
language: node_js
node_js:
- '4'
- '5'
- '6'
- '7' # Node.js 7 is most stable version
- '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
script:
- npm test
- npm run test-ui
- grunt build
after_success:
- bash <(curl -s https://codecov.io/bash)
after_script:
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
addons:
apt:
sources:

114
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,114 @@
This document was copied from its home at https://publiclab.org/conduct on October 12, 2017. See that page if you would like to submit your concerns in a safe, completely anonymous way, and to learn more about this document.
****
# Public Lab Code of Conduct
_Public Lab, PO Box 426113, Cambridge, MA 02142_
We are coming together with an intent to care for ourselves and one another. We want to nurture a compassionate democratic culture where responsibility is shared. We -- visitors, community members, community moderators, staff, organizers, sponsors, and all others -- hold ourselves accountable to the same values regardless of position or experience. For this to work for everybody, individual decisions will not be allowed to run counter to the welfare of other people. This community aspires to be a respectful place both during online and in-person interactions so that all people are able to fully participate with their dignity intact. This document is a piece of the culture we're creating.
This code of conduct applies to all spaces managed by the Public Lab community and non-profit, both online and in person. It was written by the Conduct Committee (formed in 2015 during Public Labs annual conference “The Barnraising”) and facilitated by staff to provide a clear set of practical guidelines for multi-day events such as Barnraisings, events led by organizers and community members, and online venues such as the website, comment threads on software platforms, chatrooms, our mailing lists, the issue tracker, and any other forums created by Public Lab which the community uses for communication.
## We come from all kinds of backgrounds
Our community is best when we fully invite and include participants from a wide range of backgrounds. We specifically design spaces to be welcoming and accessible to newcomers and folks from underrepresented groups. Public Lab is dedicated to providing a harassment-free, safe, and inclusive experience for everyone, regardless of personal and professional background, gender, gender identity and expression, style of clothing, sexual orientation, dis-/ability, physical appearance, body size, race, class, age, or religion. Public Lab resists and rejects: racism, sexism, ableism, ageism, homophobia, transphobia, body shaming, religion shaming, “geekier-than-thou” shaming, education bias, the shaming of people nursing children, and the dismissal or bullying of children or adults.
## We do not tolerate harassment or shaming
While we operate under the assumption that all people involved with Public Lab subscribe to the basic understanding laid out above, we take these issues very seriously and think they should, in general, be taken seriously. Therefore, individuals who violate this Code both in and outside of Public Lab spaces may affect their ability to participate in Public Lab ranging from temporarily being placed into online moderation to, as a last resort, expulsion from the community. If you have any questions about our commitment to this framework and/or if you are unsure about aspects of it, email conduct@publiclab.org and we will do our best to provide clarification.
## How It Works
Sometimes things go wrong. When a situation is uncomfortable, hurtful, exclusionary, or upsetting, there is a problem that should be addressed. This code of conduct is an effort to maintain a safe space for everyone, and to talk about what might happen if that space is compromised. Please see additional guidelines below for community behavior on how we expect people to interact with one another.
### Two helpful groups
__Conduct Committee (ConductCom)__: If at any time you experience something that you are not comfortable with, you may contact the Conduct Committee. As established during the 2015 Annual Barnraising, the following individuals are on the Conduct Committee: Klie Kliebert, Carla Green, Nick Shapiro, and Shannon Dosemagen, the executive director of the Public Lab nonprofit.
If you would like to have a confidential conversation, connect with ConductCom in person or email via [conduct@publiclab.org](mailto:conduct@publiclab.org). A minimum of two committee members will confer and respond as swiftly as possible. If you would prefer to speak privately with a representative of the nonprofit, please contact the executive director directly either in person or by email: [shannon@publiclab.org.](mailto:conduct@publiclab.org)
To submit a report anonymously for review by ConductCom, go online via phone or computer to our anonymous “contact” app, located at [http://bit.ly/PLReport](http://bit.ly/PLReport). This contact app will be monitored daily at 8am CST during in-person events like Barnraisings and weekly at all other times. During multi-day in-person events hosted by the Public Lab non-profit, there will also be a physical suggestion box available. This box will be monitored throughout the event and can also be used to let us know if you need us to check on an anonymous online submission sooner.
__Moderators Group:__ The moderators group is responsible for addressing immediate moderation issues that arise during online violations of the code over email lists and Public Lab community websites, as well as approving first-time posts and generally handling spam. Instructions on how to become a moderator, and, if youve been placed in moderation how to begin the process of getting out of moderation can be found at: https://publiclab.org/wiki/moderation.
****
## A Culture of Empathy
We begin interactions by acknowledging that we are part of a community with complementary goals. Different views are allowed to respectfully coexist in the same space. When something's happened and someone is uncomfortable, our first choice is to work through it. Endeavor to listen and appropriately adjust your behavior if someone approaches you privately with a request that you apologize or publicly requests that you stop an ongoing presentation. If someone questions your words, actions or motives, or "calls you out", hear their feedback and respond respectfully. Its okay to not understand why something is hurtful or causes discomfort, as long as you approach it respectfully, with empathy. Repeating hurtful behavior after it has been addressed is disrespectful and is not allowed. Doing so will result in removal and subsequent banning from in-person events and being placed into moderation in online spaces.
### The first rule of engaging with others is consent
During in-person gatherings, consent is important to highlight because the negotiation of consent can be subtle, and its easy to miss each others non-verbal cues, resulting in miscommunication and/or offense. During online interactions, consent can be even harder to distinguish.
We make guesses or assessments of consent (willingness, welcome, invitation) all the time. Then we stay open to signs that the consent isn't there. Handshakes are a clear example of consent: someone offers a hand, and you take it if you want to shake it. A friendly smile might indicate consent to start a conversation. It might not. We learn that in the interaction. Sometimes we ask directly. We are open to making mistakes, and learning from them. The more we learn to be empathetic and see other people, the more we're able to talk about consent.
Before you engage with someone on any level, be sure you have their consent. If your indications aren't being heard, you can also ask for help from other folks, especially Conduct Committee members and staff of the non-profit: "They aren't taking the hint. Will you help?" Turning a blind eye to hurtful interactions can be as bad for our community as the exchange itself. If you witness something, it's your responsibility to say something. This is how we keep each other accountable, encourage empathy, and keep our community safe.
## Guidelines for in-person community behavior
Do | Dont
----------- | -----------
Respectfully share what method works best for you, while giving others space to think differently and contribute other ideas | Disparage entire groups/sets of people for their beliefs or methods
Ask permission to take pictures of and post about others on social media (see Media Consent, above)| Upload photos, tag or mention others online without their consent
Speak your own narrative, from your own unique culture | Caricature the cultural expressions of groups you are not a member of
Model inclusionary expertise - if others in the group appear to be “lost”, slow down; stop and ask for input | Present information in a way / at a level that no one else in the room can understand, with no attempt to include others in the discussion
Create events that are all-ages appropriate | Use language that excludes youth and their experiences as vital contributors
Give everyone a chance to talk, only interrupting if absolutely necessary - for example, Code of Conduct violations | Repeatedly disrupt a discussion
Stop, listen and ask for clarification if someone perceives your behavior or presentation as violating the Code of Conduct | Ignore others request to stop potentially harmful behavior, even if it was an accident
Cultivate a sense of humor based on other subjects, such as word play (especially puns!) | Joke using words related to actual or insulting descriptions of people
Use words that accurately describe the situation - For example, “The wind was ridiculously strong!” instead of “The wind was crazy!” | Use disability and mental/emotional health terminology to describe a situation metaphorically, especially if the phrasing is meant as an insult
Only discuss someone elses lifestyle practices if they invite you to a conversation on the topic | Make unwelcomed comments regarding a persons lifestyle practices, including those related to food, health, parenting, relationships, and employment
Ask someone before you hug them; keep your hands/body to yourself, even when joking, unless the other person has given verbal consent | Initiate physical contact or simulate physical contact without consent
Disengage and find another activity if someone did not invite you and is not engaging with you | Violate personal space by continuing your physical presence into private spaces without consent
Exercise the right to talk about your own identity if you want to, or not if you dont want to | Deliberately “out” any aspect of a persons identity without their consent
Use the pronouns people have specified for themselves | Purposely misgender someone (ie, refusing to use their correct gender pronouns) after they have told you their correct pronouns
## Additional guidelines for online community behavior
Online modes of interaction involve large numbers of people without the helpful presence of gestural, expression, and tonal cues regarding consent. Because of this, respectful and self-aware online conduct is both especially important and difficult. Our community has evolved specific guidelines for online interactions.
_If someone violates these guidelines, someone from the Moderators group will place them into moderation by changing that persons posting permission on the relevant list, on the website, or both._
Our triple notification standard for moderation means a point person from the Moderators group will:
1. e-mail the person directly with a brief explanation of what was violated,
2. send a summary email to the rest of the moderators group,
3. if it happened on a public list (vs a website), notify the list that one of our members has been placed into moderation with a brief explanation of what is not tolerated.
If you wish to begin the process of getting out of moderation, respond to the email sent to you from [moderators@publiclab.org](mailto:moderators@publiclab.org). The Moderators group has the option to involve ConductCom.
Do | Dont
-------|--------
Stay on topic to make long threads easier to follow |Send spurious one-line responses that effectively "spam" hundreds of people and lower the overall content quality of a conversation. (Exception: expressions of appreciation and encouragement!)
Start a new thread to help others follow along. Important if your response starts to significantly diverge from the original topic | Respond with off-topic information making it hard for the large group of readers to follow along
Write short and literal subject lines to help the readers of the list manage the volume of communication | Humor and euphemisms in subject lines are easily misunderstood, although enthusiasm is welcome!
Mind your tone. We are not having this conversation in person, so it is all the more important to maintain a tone of respect | Write in aggressive tone, disrespectful tone, mocking tone, off-color tone. Note: writing in all caps is regarded as shouting
## Media Consent
* ALWAYS check with parents about posting anything with minors.
* Never post the names of minors in conjunction with their photo.
* During multi-day events like Barnraisings most people will have signed media releases. Those who havent will be responsible for placing stickers on their nametags, and/or raising their hands in the moment to alert photographers to move them out of frame.
* For events where people have not signed blanket media release forms, the photographer is responsible for letting the room know that you are taking photos that will be posted online. Pay special attention to the presence of minors and their parent's wishes.
## Addendum for all staff
Staff are bound by their Employment Handbook, you must reference it. Additionally:
* Direct problems that come up among community members to the Conduct Committee.
* When organizing events, circulate access information regarding wheelchair-accessible ADA bathrooms, non-gendered bathrooms, the presence of stairs or curb ramps in the parking lot, et cetera.
* During events that you are attending in person, solve accessibility issues by making sure attendees know where bathrooms are located and can access them by wheelchair without being obstructed by things like chairs, kites, contraptions, or cords.
* Watch for people feeling left out and include them.

377
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,377 @@
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`.
Most contribution (we imagine) would be in the form of API-compatible modules, which need not be directly included.
## Jump To
* [README.md](https://github.com/publiclab/image-sequencer)
* [Contributing Modules](#contributing-modules)
* [Info File](#info-file)
* [Ideas](#Contribution-ideas)
* [Grunt Tasks](#grunt-tasks)
****
## Contribution-ideas
See [this issue](https://github.com/publiclab/image-sequencer/issues/118) for a range of ideas for new contributions and links to possibly helpful libraries, or you can solve an [existing issue](https://github.com/publiclab/image-sequencer/labels/module). Also see the [new features issues list](https://github.com/publiclab/image-sequencer/labels/new-feature).
### Bugs
If you find a bug please list it here, and help us develop Image Sequencer by [opening an issue](https://github.com/publiclab/image-sequencer/issues/new)!
****
## Contributing modules
Most contributions can happen in modules, rather than to core library code. Modules and their [corresponding info files](#info-file) are included into the library in this file: https://github.com/publiclab/image-sequencer/blob/main/src/Modules.js#L5-L7
Module names, descriptions, and parameters are set in the `info.json` file -- [see below](#info-file).
Any module must follow this basic format:
```js
module.exports = function ModuleName(options,UI) {
var output;
// Module requirements have been simplified in version 3, see https://github.com/publiclab/image-sequencer/blob/master/CONTRIBUTING.md#contributing-modules
function draw(input,callback) {
var output = function(input){
/* do something with the input */
return input;
}
this.output = output(input); // run the output and assign it to this.output
callback();
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}
```
Image Sequencer modules are designed to be run either in the browser or in a Node.js environment. For dynamically loaded modules, that means that any uses of `require()` to include an external library must be compiled using a system like `browserify` or `webpack` to ensure browser compatibility. An example of this can be found here:
https://github.com/tech4gt/image-sequencer
### Browser/node compatibility
If you wish to offer a module without browser-compatibility, please indicate this in the returned `info` object as:
module.exports = [
ModuleName,
{ only: ['node'] }
];
If you believe that full cross-compatibility is possible, but need help, please open an issue on your module's issue tracker requesting assistance (and potentially link to it from an inline comment or the module description).
Any Independent Module Must follow this basic format
```js
function ModuleName(options,UI) {
var output;
function draw(input,callback) {
var output = function(input){
/* do something with the input */
return input;
}
this.output = output(input); // run the output and assign it to this.output
callback();
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
}
module.exports = [ModuleName,{
"name": "ModuleName",
"description": "",
"inputs": {
// inputs here
}
/* Info can be defined here or imported from a json file */
// require('./info.json') This only works in node
// In a module compiled with browserify or webpack, a require() can be used to
// load a standard info.json file.
];
```
### Running a browser-only module in node
If your module has browser specific code or you are consuming a dependency which does the `gl-context` api. We designed this api especially for webl based modules but since it runs the module in a headless browser, ti supports all browser specific APIs.
The api must be used in the following format
```js
var step = this;
if (!options.inBrowser) {
require('../_nomodule/gl-context')(input, callback, step, options);
}
else {
/* Browser specific code */
}
```
### options
The object `options` stores some important information. This is how you can accept
input from users. If you require a variable "x" from the user and the user passes
it in, you will be able to access it as `options.x`.
Options also has some in-built properties. The `options.inBrowser` boolean denotes
whether your module is being run on a browser.
### draw()
To add a module to Image Sequencer, it must have a `draw` method; you can wrap an existing module to add them:
* `module.draw(input, callback)`
The `draw` method should accept an `input` parameter, which will be an object of the form:
```js
input = {
src: "datauri of an image here",
format: "jpeg/png/etc",
// utility functions
getPixels: "function to get Image pixels. Wrapper around https://npmjs.com/get-pixels",
savePixels: "function to save Image pixels. Wrapper around https://npmjs.com/save-pixels",
lodash: "wrapper around lodash library, https://github.com/lodash",
dataUriToBuffer: "wrapper around https://www.npmjs.com/package/data-uri-to-buffer",
pixelManipulation: "general purpose pixel manipulation API, see https://github.com/publiclab/image-sequencer/blob/master/src/modules/_nomodule/PixelManipulation.js"
}
```
For example usage of pixelManipulation see https://github.com/publiclab/image-sequencer/blob/main/src/modules/Invert/Module.js
**The module is included in the browser inside a script tag and since the code runs directly in the browser if any other module is required apart from the apis available on the input object, it should be either bundled with the module code and imported in es6 format or the module code must be browserified before distribution for browser**
The draw method is run every time the step is `run` using `sequencer.run()`.
So any calculations must go **into** the `draw()` method's definition.
What is not in the draw method, but is in the `module.exports` is executed only
when the step is added. So whatever external npm modules are to be loaded, or
constant definitions must be done **outside** the `draw()` method's definition.
`draw()` receives two arguments - `input` and `callback` :
* `input` is an object which is essentially the output of the previous step.
```js
input = {
src: "<$DataURL>",
format: "<png|jpeg|gif>"
}
```
* `callback` is a function which is responsible to tell the sequencer that the step has been "drawn".
When you have done your calculations and produced an image output, you are required to set `this.output` to an object similar to what the input object was, call `callback()`, and set `options.step.output` equal to the output DataURL
* `progressObj` is an optional additional Object that can be passed in the format `draw(input, callback, progressObj)`, which handles the progress output; see [Progress reporting](#progress-reporting) below.
### UI Methods
The module is responsible for emitting various events for the UI to capture.
There are four events in all:
* `UI.onSetup(options.step)` must be emitted when the module is added. So it must be emitted outside the draw method's definition as shown above.
* `UI.onDraw(options.step)` must be emitted whenever the `draw()` method is called. So it should ideally be the first line of the definition of the `draw` method.
* `UI.onComplete(options.step)` must be emitted whenever the output of a draw call
is ready. An argument, that is the DataURL of the output image must be passed in.
* `UI.onRemove(options.step)` is emitted automatically and the module should not emit it.
* `UI.notify(msg,id)` must be emmited when a notification has to be produced.
### Name and description
For display in the web-based demo UI, set the `name` and `description` fields in the `info.json` file for the module.
## Info file
All module folders must have an `info.json` file which looks like the following:
```json
{
"name": "Name of Module to be displayed",
"description": "Optional longer text explanation of the module's function",
"url": "Optional link to module's source code or documentation",
"inputs": {
"var1": {
"type": "text",
"default": "default value"
}
},
"outputs": {
"out1": {
"type": "text"
}
}
}
```
Types may be one of "text", "integer", "float", "select".
Integer and Float types should also specify minimum and maximum values like this:
```json
"var1": {
"type": "integer",
"min": 0,
"max": 4,
"default": 1
}
```
Similarly, "Select" type inputs should have a `values` array.
Also, A module may have output values. These must be defined as shown above.
### Progress reporting
The default "loading spinner" can be optionally overriden with a custom progress object to draw progress on the CLI, following is a basic module format for the same:
```js
module.exports = function ModuleName(options,UI) {
var output;
function draw(input,callback,progressObj) {
/* If you wish to supply your own progress bar you need to override progressObj */
progressObj.stop() // Stop the current progress spinner
progressObj.overrideFlag = true; // Tell image sequencer that you will supply your own progressBar
/* Override the object and give your own progress Bar */
progressObj = /* Your own progress Object */
var output = function(input){
/* do something with the input */
return input;
};
this.output = output();
callback();
}
return {
options: options,
draw: draw,
output: output,
UI: 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
The `channel` module is included into the core modules here: https://github.com/publiclab/image-sequencer/blob/main/src/Modules.js#L5-L7
For help integrating, please open an issue.
## Meta Module
IMAGE SEQUENCER supports "meta modules" -- modules made of other modules. The syntax and structure of these meta modules is very similar to standard modules. Sequencer can also genarate meta modules dynamically with the function `createMetaModule` which can be called in the following ways
```js
/* Mapping function is a function which gets the inputs of the module as argument
* and returns an array with steps mapped to their options
* See https://github.com/publiclab/image-sequencer/blob/main/src/modules/Colorbar/Module.js for example
*/
/* Module options is an object with the following keys
* infoJson: the info.json object for the module
*/
sequencer.createMetaModule(mappingFunction,moduleOptions)
/* createMetaModule returns an array of module function and info just like normal
* modules. These can also be loaded into sequencer dynamically like other modules
*/
```
A Meta module can also be contributed like a normal module with an info and a Module.js. A basic Meta module shall follow the following format
```js
// Module.js
module.exports = require('../../util/createMetaModule.js')(
function mapFunction(options) {
return [
{ 'name': 'module-name', 'options': {} },
{ 'name': 'module-name', 'options': {} },
];
}, {
infoJson: require('./info.json')
}
)[0];
```
```json
// Info
{
"name": "meta-moduleName",
"description": "",
"inputs": {
}
}
```
```js
//index.js
module.exports = [
require('./Module.js'),
require('./info.json')
]
```
All of the above can also be combined together to form a single file module.
```js
// MetaModule.js
module.exports =
sequencer.createMetaModule(
function mapFunction(options) {
return [
{ 'name': 'module-name', 'options': {} },
{ 'name': 'module-name', 'options': {} },
];
}, {
infoJson: {
"name": "meta-moduleName",
"description": "",
"inputs": {
}
}
});
```
## 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.
#### Tasks
1. **compile**: Compiles/Browserifies the dist files in `/dist/image-sequencer.js` and `/dist/image-sequencer-ui.js`.
2. **build**: Compiles the files as in the **compile** task and minifies/uglifies dist files in `/dist/image-sequencer.min.js` and `/dist/image-sequencer-ui.min.js`.
3. **watch**: Checks for any changes in the source code and runs the **compile** task if any changes are found.
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.

View File

@@ -1,41 +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');
require("matchdep")
.filterDev("grunt-*")
.forEach(grunt.loadNpmTasks);
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options : {
livereload: true
},
source: {
files: [
'src/*.js',
'src/*/*.js',
'Gruntfile.js'
],
tasks: [ 'build:js' ]
}
watch: {
options: {
livereload: true
},
browserify: {
dist: {
src: ['src/ImageSequencer.js'],
dest: 'dist/image-sequencer.js'
}
source: {
files: ["src/**/*", "Gruntfile.js", "examples/lib/*", "examples/demo.js"],
tasks: ["compile"]
}
},
});
browserify: {
core: {
src: ["src/ImageSequencer.js"],
dest: "dist/image-sequencer.js"
},
ui: {
src: ["examples/demo.js"],
dest: "dist/image-sequencer-ui.js"
},
prodcore: {
src: ["src/ImageSequencer.js"],
dest: "dist/image-sequencer.brow.js"
},
produi: {
src: ["examples/demo.js"],
dest: "dist/image-sequencer-ui.brow.js"
}
},
/* Default (development): Watch files and build on change. */
grunt.registerTask('default', ['watch']);
grunt.registerTask('build', [
'browserify:dist'
]);
uglify: {
core: {
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"
},
produi: {
src: ["dist/image-sequencer-ui.brow.js"],
dest: "dist/image-sequencer-ui.js"
}
},
browserSync: {
dev: {
options: {
watchTask: true,
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"]);
};

724
README.md
View File

@@ -1,46 +1,124 @@
Image Sequencer
====
aka "Consequencer"
[![Build Status](https://travis-ci.org/publiclab/image-sequencer.svg?branch=master)](https://travis-ci.org/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
- **Stable Branch**: https://github.com/publiclab/image-sequencer/tree/stable/
## Why
Image Sequencer is different from other image processing systems in that it's non-destructive: instead of modifying the original image, it creates a new image at each step in a sequence. This is because it:
Image Sequencer is different from other image processing systems because it's _non-destructive_: instead of modifying the original image, it **creates a new image at each step in a sequence**. This is because it:
* produces a legible trail of operations, to "show your work" for evidential, educational, or reproducibility reasons
* makes the creation of new tools or "modules" simpler -- each must accept an input image, and produce an output image
* allows many images to be run through the same sequence of steps
* allows many images to run through the same sequence of steps
* works identically in the browser, on Node.js, and on the command line
It is also for prototyping some other related ideas:
The following diagrams attempt to explain how the applications various components interconnect:
* filter-like image processing -- applying a transform to any image from a given source, like a proxy. I.e. every image tile of a satellite imagery web map
* test-based image processing -- the ability to create a sequence of steps that do the same task as some other image processing tool, provable with example before/after images to compare with
* logging of each step to produce an evidentiary record of modifications to an original image
![general diagram](https://publiclab.org/i/30547.png?s=o)
![workflow diagram](https://raw.githubusercontent.com/publiclab/image-sequencer/main/examples/images/diagram-workflows.png)
It also for prototypes other related ideas:
* filter-like image processing -- apply a transform to an image from a given source, like a proxy. I.e. [every image tile of a satellite imagery web map](https://publiclab.org/notes/warren/05-10-2018/prototype-filter-map-tiles-in-real-time-in-a-browser-with-imagesequencer-ndvi-landsat)
* test-based image processing -- the ability to create a sequence of steps that do the same task as other image processing tools, provable with example before/after images to compare with
* logging each step -- to produce an evidentiary record of modifications to an original image
* cascading changes -- change an earlier step's settings, and see those changes affect later steps
* "small modules"-based extensibility: see [Contributing](#contributing), below
* "small modules" -- based extensibility: see [Contributing](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md)
## Examples:
* [Basic example](https://jywarren.github.io/image-sequencer/)
* [NDVI example](https://jywarren.github.io/image-sequencer/examples/ndvi/) - related to [Infragram.org](http://infragram.org)
## Examples
* [Simple Demo](https://sequencer.publiclab.org)
* [Latest Beta Demo](https://beta.sequencer.publiclab.org)
A diagram of this running 5 steps on a single sample image may help explain how it works:
![example workflow](https://raw.githubusercontent.com/publiclab/image-sequencer/main/examples/images/diagram-6-steps.png)
## Jump to:
* [Installation](#installation)
* [Quick Usage](#quick-usage)
* [CLI Usage](#cli-usage)
* [Classic Usage](#classic-usage)
* [Method Chaining](#method-chaining)
* [Multiple Images](#multiple-images)
* [Creating a User Interface](#creating-a-user-interface)
* [Contributing](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md)
* [Submit a Module](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md#contributing-modules)
* [Get Demo Bookmarklet](https://publiclab.org/w/imagesequencerbookmarklet)
## Installation
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 `npm run setup` followed by `npm start`.
### Windows
Our npm scripts do not support windows shells, please run the following snippet in PowerShell.
```powershell
npm i ; npm i -g grunt grunt-cli ; grunt build; grunt serve
```
In case of a port conflict please run the following
```powershell
npm i -g http-server ; http-server -p 3000
```
### Browser
Just include [image-sequencer.min.js](https://github.com/publiclab/image-sequencer/blob/stable/dist/image-sequencer.min.js) in the Head section of your web page. See the [demo here](https://sequencer.publiclab.org)!
### Node (via NPM)
(You must have NPM for this)
Add `image-sequencer` to your list of dependencies and run `npm install`
### CLI
Globally install Image Sequencer:
```
$ npm install image-sequencer -g
```
(You should have Node.JS and NPM for this.)
### To run the debug script
```
$ npm run debug invert
```
## Quick Usage
### Initializing the Sequencer
The Image Sequencer Library exports a function ImageSequencer which initializes a sequencer.
```js
var sequencer = ImageSequencer();
```
Image Sequencer can be used to run modules on an HTML Image Element using the
`replaceImage` method. The method accepts two parameters - `selector` and `steps`.
`replaceImage` method, which accepts two parameters - `selector` and `steps`.
`selector` is a CSS selector. If it matches multiple images, all images will be
modified. `steps` may be the name of a module or array of names of modules.
Note: Browser CORS Restrictions apply. Some browsers may not allow local images
form other folders, and throw a Security Error instead.
from other folders, and throw a Security Error instead.
```js
sequencer.replaceImage(selector,steps,optional_options);
```
`optional_options` allows to pass additional arguments to the module itself.
`optional_options` allows passing additional arguments to the module itself.
For example:
@@ -49,6 +127,66 @@ For example:
sequencer.replaceImage('#photo',['invert','ndvi-red']);
```
### Data URL usage
Since Image Sequencer uses data-urls, you can initiate a new sequence by providing an image in the [data URL format](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs), which will import into the demo and run:
[Try this example link with a very small Data URL](http://sequencer.publiclab.org/examples/#src=data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAQABADASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAf/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAABgj/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABykX//Z&steps=invert{})
To produce a data URL from an HTML image, see [this nice blog post with example code](https://davidwalsh.name/convert-image-data-uri-javascript).
## CLI Usage
Image Sequencer also provides a CLI for applying operations to local files. The CLI takes the following arguments:
-i | --image [PATH/URL] | Input image URL. (required)
-s | --step [step-name] | Name of the step to be added. (required)
-b | --basic | Basic mode only outputs the final image
-o | --output [PATH] | Directory where output will be stored. (optional)
-c | --config {object} | Options for the step. (optional)
--save-sequence [string] | Name space separated with Stringified sequence to save
--install-module [string] | Module name space seaprated npm package name
The basic format for using the CLI is as follows:
```
$ ./index.js -i [PATH] -s step-name
```
*NOTE:* On Windows you'll have to use `node index.js` instead of `./index.js`.
The CLI also can take multiple steps at once, like so:
```
$ ./index.js -i [PATH] -s "step-name-1 step-name-2 ..."
```
But for this, double quotes must wrap the space-separated steps.
Options for the steps can be passed in one line as JSON in the details option like
```
$ ./index.js -i [PATH] -s "brightness" -c '{"brightness":50}'
```
Or the values can be given through the terminal prompt like
<img width="1436" alt="screen shot 2018-02-14 at 5 18 50 pm" src="https://user-images.githubusercontent.com/25617855/36202790-3c6e8204-11ab-11e8-9e17-7f3387ab0158.png">
`save-sequence` option can be used to save a sequence and the associated options for later usage. You should provide a string which contains a name of the sequence space separated from the sequence of steps which constitute it.
```shell
sequencer --save-sequence "invert-colormap invert(),colormap()"
```
`install-module` option can be used to install new modules from npm. You can register this module in your sequencer with a custom namespace separated with the npm package name. Below is an example of the `image-sequencer-invert` module.
```shell
sequencer --install-module "invert image-sequencer-invert"
```
The CLI is also chainable with other commands using `&&`
```
sequencer -i <Image Path> -s <steps> && mv <Output Image Path> <New path>
```
## Classic Usage
@@ -68,15 +206,30 @@ a name and an image. The method also accepts an optional callback.
```js
sequencer.loadImage(image_src,optional_callback);
```
On `Node.js` the `image_src` may be a DataURI or a local path. On browsers, it
must be a DatURI (or 'selector to image' -- Work in Progress)
On `Node.js` the `image_src` may be a DataURI or a local path or a URL.
return value: **`sequencer`** (To allow method chaining)
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
return value: **none** (A callback should be used to ensure the image gets loaded)
The callback is called within the scope of a sequencer. For example:
(addSteps is defined later)
```js
sequencer.loadImage('SRC',function(){
this.addSteps('module-name');
});
```
The `this` refers to all the images added in the parent `loadImages` function only.
In this case, only `'SRC'`.
### Adding steps to the image
The `addSteps` method is used to add steps on the image. One or more steps can
The `addSteps` method is used to add steps to the image. One or more steps can
be added at a time. Each step is called a module.
```js
@@ -84,11 +237,11 @@ sequencer.addSteps(modules, optional_options);
```
If only one module is to be added, `modules` is simply the name of the module.
If multiple images are to be added, `modules` is an array of the names of modules
which are to be added, in that particular order.
If multiple images are to be added, `modules` is an array, which holds the names of modules
to be added, in that particular order.
optional_otions is just additional parameters, in object form, which you might
want to provide to the modules. It's an optional parameter.
optional_otions is just an optional parameter, in object form, which you might
want to provide to the modules.
return value: **`sequencer`** (To allow method chaining)
@@ -102,13 +255,35 @@ modules.
sequencer.run();
```
Additionally, an optional callback can be passed to this method.
Sequencer can be run with a custom config object
```js
sequencer.run(function(out){
// The config object enables custom progress bars in a node environment and
// ability to run the sequencer from a particular index(of the steps array)
sequencer.run(config);
```
The config object can have the following keys
```js
config: {
progressObj: , //A custom object to handle progress bar
index: //Index to run the sequencer from (defaults to 0)
}
```
Additionally, an optional callback function can be passed to this method.
```js
sequencer.run(function callback(out){
// this gets called back.
// "out" is the DataURL of the final image.
});
sequencer.run(config,function callback(out){
// the callback is supported by all types of invocations
});
```
return value: **`sequencer`** (To allow method chaining)
@@ -117,7 +292,7 @@ return value: **`sequencer`** (To allow method chaining)
### Removing a step from the sequencer
The `removeSteps` method is used to remove unwanted steps from the sequencer.
It accepts the index of the step as an input, or an array of the unwanted indices
It accepts the index of the step as an input or an array of the unwanted indices,
if there are more than one.
For example, if the modules ['ndvi-red','crop','invert'] were added in this order,
@@ -137,14 +312,14 @@ return value: **`sequencer`** (To allow method chaining)
### Inserting a step in between the sequencer
The `insertSteps` method can be used to insert one or more steps at a given index
in the sequencer. It accepts the index where the module is to be inserted, name of
in the sequencer. It accepts the index where the module is to be inserted, the name of
the module, and an optional options parameter. `index` is the index of the inserted
step. Only one step can be inserted at a time. `optional_options` plays the same
role it played in `addSteps`.
Indexes can be negative. Negative sign with an index means that counting will be
done in reverse order. If the index is out of bounds, the counting will wrap in
the original direction of counting. So, an `index` of -1 means that the module is
the original direction of counting. So, an `index` of -1 means the module is
inserted at the end.
```js
@@ -153,20 +328,32 @@ sequencer.insertSteps(index,module_name,optional_options);
return value: **`sequencer`** (To allow method chaining)
### Importing an independent module
The `loadNewModule` method can be used to import a new module inside the sequencer. Modules can be downloaded via npm, yarn or CDN and are imported with a custom name. If you wish to load a new module at runtime, it will need to avoid using `require()` -- unless it is compiled with a system like browserify or webpack.
```js
const module = require('sequencer-moduleName')
sequencer.loadNewModule('moduleName',module);
```
## Method Chaining
Methods can be chained on the Image Sequencer:
* loadImage()/loadImages() can only terminate a chain.
* run() can not be in the middle of the chain.
* If the chain starts with loadImage() or loadImages(), the following methods are
applied only to the newly loaded images.
* If no name is provided to the image, a name will be generated for it. The name will
be of the form "image<number>". For ex: "image1", "image2", "image3", etc.
Valid Chains:
```js
sequencer.loadImage('red').addSteps('invert').run(function(out){
//do something with otuput.
});
sequencer.loadImage(function(){
this.addSteps('invert').run(function(out){
//do something with ouptut.
});
})
sequencer.addSteps(['ndvi-red','invert']).run();
et cetra.
```
@@ -177,352 +364,183 @@ sequencer.addSteps('invert').run().addSteps('ndvi-red');
```
## Multiple Images
Image Sequencer is capable of handling multiple images at once.
### Initializing a sequencer with multiple images.
This is just like before.
## Fetching current steps
The `getSteps` method can be used to get the array of current steps in `this` instance of sequencer.For example
```js
var sequencer = ImageSequencer();
sequencer.getSteps()
```
### Loading Multiple Images into the Sequencer
returns an array of steps associated with the current sequencer.
Multiple images can be loaded by the method `loadImages`. Everything is the same,
except that now, a unique identification called `image_name` has to be provided
with each image. This is a string literal.
## Saving Sequences
* 3/2 parameters :
```js
sequencer.loadImages(image_name,
image_src,optional_callback);
```
* 1/2 parameters (JSON) :
```js
sequencer.loadImages({
images: {
image1_name: image_src,
image2_name: image_src,
...
},
callback: optional_callback
});
```
IMAGE SEQUENCER supports saving a sequence of modules and their associated settings in a simple string syntax. These sequences can be saved in the local storage of the browser and inside a JSON file in node.js. sequences can be saved in node context using the CLI option
return value: **`sequencer`** (To allow method chaining)
### Adding Steps on Multiple Images
The same method `addSteps` is used for this. There's just a slight obvious change
in the syntax that the image name has to be supplied too. `image_name` as well as
`module_name` in the following examples can be either strings or arrays of strings.
```js
sequencer.addSteps(image_name,module_name,optional_options);
```shell
--save-sequence "name stringified-sequence"
```
If no Image Name is specified, the module is added to **all** images.
In Node and the browser the following function can be used
```js
sequencer.addSteps(module_name,optional_options);
sequencer.saveSequence(name,sequenceString)
```
All this can be passed in as JSON:
The function `sequencer.loadModules()` reloads the modules and the saved sequences into `sequencer.modules` and `sequencer.sequences`
## String syntax
Image sequencer supports stringifying a sequence which is appended to the url and hence can then be shared. An example below shows the string syntax for `channel` and `invert` module
```
channel{channel:green},invert{}
```
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()
```
Following are the core API functions that can be used to stringify and jsonify steps.
```js
sequencer.toString() //returns the stringified sequence of current steps
sequencer.toJSON(str) // returns the JSON for the current sequence
sequencer.stringToJSON(str) // returns the JSON for given stringified sequence
sequencer.importString(str) //Imports the sequence of steps into sequencer
sequencer.importJSON(obj) //Imports the given sequence of JSON steps into sequencer
```
Image Sequencer can also generate a string for usage in the CLI for the current sequence of steps:
```js
sequencer.toCliString()
```
## Importing steps using JSON array
Image sequencer provides the following core API function to import the given sequence of JSON steps into sequencer.
```js
sequencer.addSteps({
image1_name: {name: module_name, o: optional_options},
image2_name: {name: module_name, o: optional_options},
...
sequencer.importJSON(obj)
```
It can be implemented the following way for example:
```js
sequencer.importJSON([
{ name: 'blur', options: {} }
]);
```
where name is the name of step to be added, options object can be the one used to provide various params to the sequencer which can customise the default ones.
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
Image Sequencer provides the following events which can be used to generate a UI:
* `onSetup` : this event is triggered when a new module is set up. This can be used,
for instance, to generate a DIV element to store the generated image for that step.
* `onDraw` : This event is triggered when Image Sequencer starts drawing the output
for a module. This can be used, for instance, to overlay a loading GIF over the DIV
generated above.
* `onComplete` : This event is triggered when Image Sequencer has drawn the output
for a module. This can be used, for instance, to update the DIV with the new image
and remove the loading GIF generated above.
* `onRemove` : This event is triggered when a module is removed. This can be used,
for instance, to remove the DIV generated above.
* `notify` : This event is triggered whenever we need to shoot a notification to the
user-interface.For example when the step is not available, we can shoot a notification,
by sending appropriate message.For HTML UI it adds a DOM node to the browser, for CLI
and node , it logs the notification output to the respective console.
How to define these functions:
```js
sequencer.setUI({
onSetup: function(step) {},
onDraw: function(step) {},
onComplete: function(step) {},
onRemove: function(step) {},
notify: function(msg,id) {}
});
```
return value: **`sequencer`** (To allow method chaining)
These methods can be defined and re-defined at any time, but it is advisable to
set them before any module is added and not change it thereafter. This is because
the `setUI` method will only affect the modules added after `setUI` is called.
The `onComplete` event is passed on the output of the module.
### Running a Sequencer with multiple images
Image Sequencer provides a namespace `step` for the purpose of UI Creation in
the scope of these definable function. This namespace has the following
predefined properties:
The same `run` method can be used with a slight change in syntax.
The `run` method accepts parameters `image` and `from`. `from` is the index from
where the function starts generating output. By default, it will run across all
the steps. (from = 1) If no image is specified, the sequencer will be run over **all
the images**. `image_name` may be an array of image names.
* `step.name` : (String) Name of the step
* `step.ID` : (Number) An ID given to every step of the sequencer, unique throughout.
* `step.imageName` : (String) Name of the image the step is applied to.
* `step.output` : (DataURL String) Output of the step.
* `step.inBrowser` : (Boolean) Whether the client is a browser or not
In addition to these, one might define their own properties, which shall be
accessible across all the event scopes of that step.
For example :
```js
sequencer.run(); //All images from first step
```
```js
sequencer.run(image_name,from); //Image 'image' from 'from'
```
The `run` method also accepts an optional callback just like before:
```js
sequencer.run(image_name,from,function(out){
// This gets called back.
// "out" is the DataURL of final image.
});
```
JSON Input is also acceptable.
```js
sequencer.run({
image1_name: from,
image2_name: from,
...
});
```
return value: **`sequencer`** (To allow method chaining)
### Removing Steps from an Image
Similarly, `removeSteps` can also accept an `image_name` parameter. Either, both,
or none of `image_name` and `steps` them may be an array. JSON input is also acceptable.
```js
sequencer.removeSteps("image_name",[steps]);
```
```js
sequencer.removeSteps("image_name",step);
```
```js
sequencer.removeSteps({
image1_name: [steps],
image2_name: [steps],
...
});
```
return value: **`sequencer`** (To allow method chaining)
### Inserting steps on an image
The `insertSteps` method can also accept an `image_name` parameter. `image_name`
may be an array. Everything else remains the same. JSON Inout is acceptable too.
```js
sequencer.insertSteps("image",index,"module_name",o);
```
```js
sequencer.insertSteps([image],index,"module_name",o);
```
```js
sequencer.insertSteps({
image1: [
{index:index1, name: module_name1, o:optional_options1},
{index:index2, name: module_name2, o:optional_options2},
...
]
});
```
return value: **`sequencer`** (To allow method chaining)
## Contributing
Happily accepting pull requests; to edit the core library, modify files in `/src/`. To build, run `npm install` and `grunt build`.
### Contributing modules
Most contribution (we imagine) would be in the form of API-compatible modules, which need not be directly included.
#### draw()
To add a module to Image Sequencer, it must have the following method; you can wrap an existing module to add them:
* `module.draw()`
The `draw(input,callback)` method should accept an `input` parameter, which will be an object of the form:
```js
input = {
src: "datauri here",
format: "jpeg/png/etc"
}
```
The `image` object is essentially the output of the previous step.
The draw method must, when it is complete, pass the output image to the method `this.output = modified_input`, which will send the output to the next module in the chain. For example:
```js
function draw(image) {
// do some stuff with the image
this.output = image;
callback();
}
```
#### Title
For display in the web-based UI, each module may also have a title like `options.title`.
#### Module example
See existing module `green-channel` for an example: https://github.com/jywarren/image-sequencer/tree/master/src/modules/GreenChannel.js
For help integrating, please open an issue.
****
## Development
Notes on development next steps:
### UI
* [ ] add createUserInterface() which is set up by default to draw on ImageBoardUI, but could be swapped for nothing, or an equiv. lib
* [ ] it could create the interface and use event listeners like module.on('draw', fn()); to update the interface
* [ ] spinners before panels are complete
* [ ] is there a module for generating forms from parameters?
* [ ] click to expand for all images
* [ ] `ImageSequencer.Renderer` class to manage image output formats and adapters
* [ ] remove step
* [ ] output besides an image -- like `message(txt)` to display to the step's UI
### Modularization
* [ ] remotely includable modules, not compiled in -- see plugin structures in other libs
* [x] ability to start running at any point -- already works?
* [x] commandline runnability?
* [x] Make available as browserified OR `require()` includable...
* [ ] standardize panel addition with submodule that offers Panel.display(image)
* [ ] allow passing data as data-uri or Image object, or stream, or ndarray or ImageData array, if both of neighboring pair has ability?
* see https://github.com/jywarren/image-sequencer/issues/1
* [ ] ...could we directly include package.json for module descriptions? At least as a fallback.
* [ ] (for node-and-line style UIs) non-linear sequences with Y-splitters
* [ ] `sequencer.addModule('path/to/module.js')` style module addition -- also to avoid browserifying all of Plotly :-P
* [x] remove step
### Testing
* [ ] tests - modules headless; unit tests
* [ ] comparisons with diff
* [ ] testing a module's promised functionality: each module could offer before/after images as part of their API; by running the module on the before image, you should get exactly the after image, comparing with an image diff
### Use cases
* [ ] make an Infragram module that accepts a math expression
### Bugs
* [x] BUG: this doesn't work for defaults: imageboard.loadImage('examples/grid.png', function() {});
* we should make defaults a config of the first module
****
## Module Candidates
* https://github.com/linuxenko/rextract.js
* https://www.npmjs.com/package/histogram
* https://github.com/hughsk/flood-fill
* https://www.npmjs.com/package/blink-diff
* smaller and faster: https://www.npmjs.com/package/@schornio/pixelmatch
* https://github.com/yahoo/pngjs-image has lots of useful general-purpose image getters like `image.getLuminosityAtIndex(idx)`
* some way to add in a new image (respecting alpha) -- `add-image` (with blend mode, default `normal`?)
* https://github.com/yuta1984/CannyJS - edge detection
* http://codepen.io/taylorcoffelt/pen/EsCcr - more edge detection
## Ideas
* https://github.com/vicapow/jsqrcode
* https://github.com/jadnco/whirl - scrubbable image sequence player
* non graphics card GL functions could be shimmed with https://github.com/Overv/JSGL
* or this: https://github.com/stackgl/headless-gl
* https://github.com/mattdesl/fontpath-simple-renderer
* output in animated Gif? as a module
### Referencing earlier states
Complex sequences with masking could require accessing previous states (or nonlinearity):
* flood-fill an area
* select only the flooded area
* roundabout: lighten everything to <50%, then flood-fill with black? Not 100% reliable.
* roundabout 2: `flood fill`, then `blink-diff` with original
* then add step which recovers original image, repeat `flood-fill`/`blink-diff` for second region
* reference above masked states in a `mask` module, with `maskModule.draw(image, { getMask: function() { return maskImg } })`
****
**Notes:**
`pattern-fill` module to use patterns in JS canvas:
```js
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("lamp");
var pat=ctx.createPattern(img,"repeat");
ctx.rect(0,0,150,100);
ctx.fillStyle=pat;
ctx.fill();
```
Masking:
```js
ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(160, 600);
ctx.rect(0, 0, 160, 600);
ctx.closePath();
ctx.clip();
ctx.drawImage(img, 0, 0);
ctx.restore();
```
****
## UI notes:
* visual nodes-and-lines UI: https://github.com/flowhub/the-graph
* https://flowhub.github.io/the-graph/examples/demo-simple.html
```js
settings: {
'threshold': {
type: 'slider',
label: 'Threshold',
default: 50,
min: 0,
max: 100
sequencer.setUI({
onSetup: function(step){
// Create new property "step.image"
step.image = document.createElement('img');
document.body.append(step.image);
},
'colors': {
type: 'select',
label: 'Colors',
options: [
{ name: '0', value: '0', default: true },
{ name: '1', value: '1' },
{ name: '2', value: '2' }
]
onComplete: function(step){
// Access predefined "step.output" and user-defined "step.image"
step.image.src = step.output;
},
onRemove: function(step){
// Access user-defined "step.image"
step.image.remove();
}
}
});
```
Possible web-based commandline interface: https://hyper.is/?
## Using multiple images on same sequencer:
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.
```js
s1 = new ImageSequencer(...);
s1.loadImage(url1);
s1.addSteps('blur');
s1.run();
s1.addImage(url2);
s1.run();
```
However if we want to use more than one image, we can either initialize a sequencer for each image like:
```js
sequencer1 = new ImageSequencer(...);
sequencer1.loadImage(...);
sequencer1.addSteps(steps);
sequencer1.run();
sequencer2 = new ImageSequencer(...);
sequencer2.loadImage(...);
sequencer2.addSteps(steps);
sequencer2.run();
```
### Path cutting
* threshold
* vectorize
* edge detect
* direction find (vectorize and colorize)
**Note**: Details of all modules can be sought using `sequencer.modulesInfo()`.
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.

35523
dist/image-sequencer.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,47 @@
Documentation of various Modules
===
## Crop Module (crop)
List of Module Documentations
1. [Crop](#crop-module)
2. [Segmented-Colormap](#segmented-colormap-module)
3. [FisheyeGl](#fisheyeGl-module)
4. [Add QR](#Add-QR-module)
5. [Average](#average-module)
6. [Blend](#blend-module)
7. [Blur](#blur-module)
8. [Brightness](#brightness-module)
9. [Channel](#channel-module)
10. [Colorbar](#colorbar-module)
11. [Colormap](#colormap-module)
12. [Contrast](#contrast-module)
13. [Convolution](#convolution-module)
14. [DecodeQr](#decodeQr-module)
15. [Dither](#dither-module)
16. [DrawRectangle](#draw-rectangle-module)
17. [Dynamic](#dynamic-module)
18. [Edge-Detect](#edge-detect-module)
19. [FlipImage](#flipimage-module)
20. [Gamma-Correction](#gamma-correction-module)
21. [Gradient](#gradient-module)
22. [Histogram](#histogram-module)
23. [Import-image](#import-image-module)
24. [Invert](#invert-module)
25. [Ndvi](#ndvi-module)
26. [Ndvi-Colormap](#ndvi-colormap-module)
27. [Overlay](#overlay-module)
28. [PaintBucket](#paint-bucket-module)
29. [Resize](#resize-module)
30. [ReplaceColor](#replacecolor-module)
31. [Rotate](#rotate-module)
32. [Saturation](#saturation-module)
33. [Threshold](#threshold)
34. [Tint](#tint)
35. [ColorTemperature](#color-temperature)
36. [Grid-Overlay](#grid-overlay)
## crop-module
This module is used to crop an image.
@@ -24,7 +64,7 @@ Where `options` is an object having the properties `x`, `y`, `w`, `h`. This diag
* `options.h` : half of image height
## Segmented Colormap Module (segmented-colormap)
## segmented-colormap-module
This module is used to map the pixels of the image to a segmented colormap.
@@ -47,3 +87,517 @@ where `options` is an object with the property `colormap`. `options.colormap` ca
* "fastie" : [[0, [255, 255, 255], [0, 0, 0]], [0.167, [0, 0, 0], [255, 255, 255]], [0.33, [255, 255, 255], [0, 0, 0]], [0.5, [0, 0, 0], [140, 140, 255]], [0.55, [140, 140, 255], [0, 255, 0]], [0.63, [0, 255, 0], [255, 255, 0]], [0.75, [255, 255, 0], [255, 0, 0]], [0.95, [255, 0, 0], [255, 0, 255]]]
* A custom array.
## fisheyeGl-module
This module is used for correcting Fisheye or Lens Distortion
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('fisheye-gl',options)
.run()
```
where `options` is an object with the following properties:
* a : a correction (0 to 4; default 1)
* b : b correction (0 to 4; default 1)
* Fx : x correction (0 to 4; default 1)
* Fy : y correction (0 to 4; default 1)
* scale : The ratio to which the original image is to be scaled (0 to 20; default 1.5)
* x : Field of View x (0 to 2; default 1)
* y : Field of View y (0 to 2; default 1)
## add-qr-module
This module Adds QR corresponding to the given string.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('add-qr',options)
.run()
```
where `options` is an object with the following properties:
* size : size of QR code in pixels (default 200)
* qrCodeString : input string to generate QR code
## average-module
This module is used for averaging all the pixels of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('average',options)
.run()
```
## blend-module
This module is used for blending two images .
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('blend',options)
.run()
```
where `options` is an object with the following properties:
* offset: step of image with which current image is to be blended(Two steps back is -2, three steps back is -3 etc; default -2)
* func: function used to blend two images (default : function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] })
## blur-module
This module is used for applying a Gaussian blur effect.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('blur',options)
.run()
```
where `options` is an object with the following property:
* blur : Intensity of Gaussian blur (0 to 5; default 2)
## brightness-module
This module is used for changing the brightness of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('brightness',options)
.run()
```
where `options` is an object with the following property:
* brightness : brightness of the image in percentage (0 to 100; default 100)
## channel-module
This module is used for forming a grayscale image by applying one of the three primary colors.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('channel',options)
.run()
```
where `options` is an object with the following property:
* channel : color of the channel (red, green, blue; default green)
## colorbar-module
This module is used for displaying an image with a colorbar.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('colorbar',options)
.run()
```
where `options` is an object with the following properties:
* colormap : Name of the Colormap(default, greyscale, stretched, fastie, brntogrn, blutoredjet, colors16; default: default)
* x : X-position of the image on which the new image is overlayed (default 0)
* y : Y-position of the image on which the new image is overlayed (default 0)
* h : height of resulting cropped image (default : 50% of input image width )
## colormap-module
This module is used for mapping brightness values (average of red, green & blue) to a given color lookup table, made up of a set of one more color gradients.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('colormap',options)
.run()
```
where `options` is an object with the following property:
* colormap : Name of the Colormap ( greyscale, stretched, fastie, brntogrn, blutoredjet, colors16)
## contrast-module
This module is used for changing the contrast of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('contrast',options)
.run()
```
where `options` is an object with the following property:
* contrast : contrast for the given image (-100 to 100; default : 70)
## convolution-module
This module is used for performing image-convolution.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('convolution',options)
.run()
```
where `options` is an object with the following properties:
* constantFactor : a constant factor, multiplies all the kernel values by that factor (default : 1/9)
* kernelValues : nine space separated numbers representing the kernel values in left to right and top to bottom format(default : 1 1 1 1 1 1 1 1 1)
## decodeQr-module
This module is used for decoding a QR in image (if present).
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('decode-qr',options)
.run()
```
## dither-module
This module approximates a color from a mixture of other colors when the required color is not available, creating illusions of the color that is not present actually.
[more info on wikipedia](https://en.wikipedia.org/wiki/Dither)
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('dither',options)
.run()
```
where `options` is an object with the following property:
* dither : Can select the name of the Dithering Algorithm(default none)
## draw-rectangle-module
This module helps to draw a rectangle on the image with a starting and ending corner with the specified thickness and color of the border.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('draw-rectangle',options)
.run()
```
where `options` is an object with the following properties:
* startingX : starting x position of the rectangle (default 0)
* startingY : starting y position of the rectangle (default 0)
* endX : last x position of the rectangle (default "width")
* endY : last y position of the rectangle (default "height")
* thickness : thickness of the border (default 1)
* color : RGBA values separated by a space (default "0 0 0 255")
## dynamic-module
This module is used for producing each color channel based on the original image's color.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('dynamic',options)
.run()
```
where `options` is an object with the following properties:
* red : expression for red channel (R, G, B and A as inputs; default r)
* green : expression for green channel (R, G, B and A as inputs; default g)
* blue : expression for blue channel (R, G, B and A as inputs; default b)
* monochrome: fallback for other channels if none provided (default : r+g+b/3)
## edge-detect-module
This module is used for detecting images.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('edge-detect',options)
.run()
```
where `options` is an object with the following properties:
* blur : Intensity of Gaussian blur (0 to 5; default 2)
* highThresholdRatio : Upper Threshold Ratio ( default : 0.2)
* lowThresholdratio : Lower Threshold Ratio ( default : 0.2)
## flipimage-module
This module is used for flipping the image on the selected axis.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('flip-image',options)
.run()
```
where `options` is an object with the following properties:
* Axis : select the required axis (default : vertical)
## gamma-correction-module
This module is used for applying gamma correction.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('gamma-correction',options)
.run()
```
where `options` is an object with the following property:
* adjustment : Inverse of actual gamma factor (default 0.2)
## gradient-module
This module is used for finding gradient of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('gradient',options)
.run()
```
## histogram-module
This module is used for calculating histogram of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('histogram',options)
.run()
```
where `options` is an object with the following property:
* gradient : boolean value used to toggle gradient along x-axis (true or false; default true)
## import-image-module
This module is used for importing a new image and replacing the original with it.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('import-image',options)
.run()
```
where `options` is an object with the following property:
* url : url of the new image (local image url or data url;default : "./images/monarch.png")
## invert-module
This module is used for inverting the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('invert',options)
.run()
```
## ndvi-module
This module is used for applying ndvi technique to the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('ndvi',options)
.run()
```
where `options` is an object with the following property:
* filter : filter for NDVI (blue or red; default red)
## ndvi-colormap-module
This module is used for demonstrating ndvi and colormap properties consecutively.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('ndvi-colormap',options)
.run()
```
## overlay-module
This module is used for overlaying an Image over another .
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('overlay',options)
.run()
```
where `options` is an object with the following properties:
* x : X-position of the image on which the new image is overlayed (default 0)
* y : Y-position of the image on which the new image is overlayed (default 0)
* offset : offset to the step on which the output of the last step is overlayed (default -2)
## paint-bucket-module
This module fills any polygonal shape with the specified color in pixels.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('paint-bucket',options)
.run()
```
where `options` is an object with the following property:
* startingX : it is the value of the starting x-cordinate (default 10)
* startingY : it is the value of the starting y-cordinate (default 10)
* fillColor : they are four spaced seperated numbers representing the RGBA values of fill-color (default "100 100 100 255")
* tolerance : it is the % tolerance (default 10)
## resize-module
This module is used for resizing an image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('resize',options)
.run()
```
where `options` is an object with the following property:
* resize : Percentage value of resize (default 125%)
## replacecolor-module
This module is used in replacing the color with grey or any desired color.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('replace-color',options)
.run()
```
where `options` is an object with the following properties:
* replaceMethod : replaces with the desired color (default greyscale)
* replaceColor : three space separated numbers representing the RGB values of color to be filled (default "0 0 255")
* color : three space separated numbers representing the RGB values of color to be replaced (default "228 86 81")
* tolerance : it is the % tolerance (default 50)
## rotate-module
This module is used for rotating an image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('rotate',options)
.run()
```
where `options` is an object with the following property:
* rotate : angular value for rotation in degrees (between 0 and 360; default 0)
## saturation-module
This module is used for changing the saturation of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('saturation',options)
.run()
```
where `options` is an object with the following property:
* saturation : saturation for the new image (between 0 and 2; default 0)
## Threshold
Thresholding is used to create binary images.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('threshold',options)
.run()
```
where `options` is an object with the following property:
* threshold : it allows to select the types of thresholding (default "manual thresholding")
* input : it allows to select the range of thresholding value (default 120)
## Tint
It adds color tint to an image
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('tint',options)
.run()
```
where `options` is an object with the following property:
* color : RGB values seperated by a space (default "0 0 255")
* factor : amount of tint (default 0.5)
## Color Temperature
This changes the color temperature of the image.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('color-temperature',options)
.run()
```
where `options` is an object with the following property:
* temperature : temperature between 0 - 40,000 kelvin (default 6000)
## Grid Overlay
This adds the grid over an image.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('grid-overlay',options)
.run()
```
where `options` is an object with the following property:
* options.x : The value at which the grid line should start in x-axis.
* options.y : The value at which the grid line should start in y-axis.
* color : Color for the grid on the image.

274
examples/demo.css Normal file
View File

@@ -0,0 +1,274 @@
/* https://github.com/theleagueof/league-spartan */
@font-face {
font-family: 'League Spartan';
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot');
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot?#iefix') format('embedded-opentype'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.woff2') format('woff2'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.woff') format('woff'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.ttf') format('truetype'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.svg#league_spartanbold') format('svg');
font-weight: bold;
font-style: normal;
}
body {
padding: 20px;
margin: 0 auto 200px;
max-width: 1000px;
background: #f8f8fa;
}
footer {
margin-top: 40px;
}
h1 {
font-family: 'League Spartan';
color: #445;
}
body > .container,
body > .container-fluid {
}
.center-align {
display: flex;
justify-content: center;
text-align:center;
}
.header {
text-align: center;
}
.panel {
margin-left: 20px;
margin-right: 20px;
}
.nomargin {
margin: 0 !important;
}
.form-control[type="range"] {
padding: 0px 0px;
}
.dropzone {
padding: 30px;
margin: 0 20% 30px;
border: 4px dashed #ccc;
border-radius: 8px;
text-align: center;
color: #444;
}
.hover {
background: #eee;
}
.dropzone input {
max-width: 100%;
}
.step {
margin-bottom: 20px;
}
.step .img-thumbnail {
margin-bottom: 20px;
}
.det {
padding: 10px 16px;
text-decoration: italic;
}
.tools {
margin: 10px 0;
}
.load {
padding: 30px;
background: #eee;
border-radius: 8px;
text-align: center;
font-size: 2em;
color: #444;
}
#addStep {
max-width: 500px;
margin: 20px auto;
}
#add-step-btn{
margin-left: 10px;
}
#addStep .labels {
text-align: right;
padding: 6px;
margin: 2px;
font-weight: bold;
}
@media (max-width:768px) {
#addStep .labels {
text-align: left;
}
}
#addStep .add {
text-align: center;
margin: 10px;
}
#save-seq {
display: block;
margin: 0px 10px 0px 0px;
width: 250px;
}
.info {
padding: 8px;
text-align: center;
}
#gif {
display: block;
margin: 0px 0px 0px 10px;
width: 250px;
}
#dwnld {
max-width: 500px;
margin: 20px auto;
margin-left: 5px;
}
#gif_element {
display: block;
margin: 0 auto;
width: 100%;
height: auto;
}
#move-up {
position: fixed;
bottom: 50px;
right: 40px;
z-index: 550;
display: none;
background:transparent;
border:none;
}
#move-up i {
font-size:60px;
opacity:0.7;
color:#BABABA;
}
.btn-circle{
min-width: 80px;
min-height: 80px;
text-align: center;
display: flex !important;
flex-direction: column;
padding: 6px 0;
font-size: 12px;
line-height: 1.42;
border-radius: 10px;
margin-left: 5px;
margin-right: 5px;
}
.radio{
cursor:pointer;
overflow: hidden;
height: 80px;
width: 80px;
margin-left: 5px;
margin-right: 5px;
}
.radio-group {
margin-bottom: 20px;
overflow: auto;
}
.no-border {
border: 0px;
}
.savesequencemsg{
display: none;
text-align: center;
}
.notification {
background-color: #808b96;
padding:4px;
color:white;
border-radius:3px;
font-size:2rem;
position:fixed;
bottom:2px;
left:50%;
min-width:14rem;
text-align:center;
display:none;
transform: translate(-50%, -50%);
}
#resetButton {
margin-top: 20px;
}
.i-over {
position: absolute;
left: 15px;
top: 15px;
z-index: 2;
color: white;
}
.i-small {
left: 25px;
}
@media all and (max-width: 767px) {
.center-align {
justify-content: space-between;
}
}
a.name-header{
text-decoration: none;
color: #445;
}
.step-column{
display:flex;
align-content: center;
justify-content: center;
}
.trash-container button.btn-xs {
margin-top: -5px !important;
}
.toggleIcon {
transition: transform 0.2s;
}
.rotated {
transform: rotate(180deg);
}
#gif{
margin-left:0px;
margin-top:5px;
width:100%;
}
.save-button{
margin-top:20px;
margin-bottom:0px;
align:center;
width:100%;
}

225
examples/demo.js Normal file
View File

@@ -0,0 +1,225 @@
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');
window.onload = function() {
sequencer = ImageSequencer();
function refreshOptions() {
// Load information of all modules (Name, Inputs, Outputs)
var modulesInfo = sequencer.modulesInfo();
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>"
);
}
// Null option
addStepSelect.append('<option value="" disabled selected>Select a Module</option>');
addStepSelect.selectize({
sortField: 'text'
});
}
refreshOptions();
$(window).on('scroll', scrollFunction);
function scrollFunction() {
var shouldDisplay = $('body').scrollTop() > 20 || $(':root').scrollTop() > 20;
$('#move-up').css({
display: shouldDisplay ? 'block' : 'none'
});
}
function topFunction() {
$('body').animate({scrollTop: 0});
$(':root').animate({scrollTop: 0});
}
$('#move-up').on("click",topFunction);
// UI for each step:
sequencer.setUI(DefaultHtmlStepUi(sequencer));
// UI for the overall demo:
var ui = defaultHtmlSequencerUi(sequencer);
// find any `src` parameters in URL hash and attempt to source image from them and run the sequencer
if (urlHash.getUrlHashParameter('src')) {
sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad);
} else {
sequencer.loadImage("images/tulips.png", ui.onLoad);
}
var resetSequence = function(){
var r=confirm("Do you want to reset the sequence?");
if (r)
window.location = "/";
}
$("#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() {
$(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);
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);
}
$('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).");
if(result){
result = result + " (local)";
sequencer.saveSequence(result, sequencer.toString());
sequencer.loadModules();
displayMessageOnSaveSequence();
refreshOptions();
}
});
var isWorkingOnGifGeneration = false;
$('.js-view-as-gif').on('click', function(event) {
// Prevent user from triggering generation multiple times
if (isWorkingOnGifGeneration) return;
isWorkingOnGifGeneration = true;
var button = event.target;
button.disabled = true;
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 imgSrcs = [];
for (var i = 0; i < imgs.length; i++) {
imgSrcs.push(imgs[i].src);
}
var options = {
'gifWidth': imgs[0].width,
'gifHeight': imgs[0].height,
'images': imgSrcs,
'frameDuration': 7,
}
gifshot.createGIF(options, function(obj) {
if (!obj.error) {
// Final gif encoded with base64 format
var image = obj.image;
var animatedImage = document.createElement('img');
animatedImage.id = "gif_element";
animatedImage.src = image;
var modal = $('#js-download-gif-modal');
$("#js-download-as-gif-button").one("click", function() {
// Trigger download
download(image, "index.gif", "image/gif");
// Close modal
modal.modal('hide');
})
var gifContainer = document.getElementById("js-download-modal-gif-container");
// Clear previous results
gifContainer.innerHTML = '';
// Insert image
gifContainer.appendChild(animatedImage);
// Open modal
modal.modal();
button.disabled = false;
button.innerHTML = 'View GIF';
isWorkingOnGifGeneration = false;
}
});
}
catch (e) {
console.error(e);
button.disabled = false;
button.innerHTML = 'View GIF';
isWorkingOnGifGeneration = false;
}
});
// image selection and drag/drop handling from examples/lib/imageSelection.js
sequencer.setInputStep({
dropZoneSelector: "#dropzone",
fileInputSelector: "#fileInput",
takePhotoSelector: "#take-photo",
onLoad: function onFileReaderLoad(progress) {
var reader = progress.target;
var step = sequencer.steps[0];
var util= intermediateHtmlStepUi(sequencer);
step.output.src = reader.result;
sequencer.run({ index: 0 });
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');
},
onTakePhoto: function (url) {
var step = sequencer.steps[0];
step.output.src = url;
sequencer.run({ index: 0 });
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');
}
});
setupCache();
if (urlHash.getUrlHashParameter('src')) {
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'),'#addStep');
} else {
insertPreview.updatePreviews("images/tulips.png",'#addStep');
}
};

137
examples/fisheye.html Normal file
View File

@@ -0,0 +1,137 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fisheye Removal | Image Sequencer</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<link rel="stylesheet" href="demo.css">
<style media="screen">
.r.18 {
font-size: 18px !important;
}
.m {
margin: 0 5px;
}
div.c.m {
width: 100px;
}
.r span {
width: 30px !important;
}
@media all and (max-width: 1000px) {
div#main {
flex-direction: column;
}
}
</style>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../dist/image-sequencer.js"></script>
</head>
<body>
<div class="wrapper">
<header>
<h2>Image Sequencer</h2>
<h5>FisheyeGl Demo</h5>
</header>
<section class="rh">
<div class="r">
Drag the Slider to adjust values
</div>
<div class="r">
Select an Image <input type="file" id="file" value="">
</div>
<div class="r" id="main">
<div class="c">
<img id="fisheye" src="" alt="">
</div>
<div class="c rh">
<div class="r 18">
<div class="c m 30">Fx:</div>
<input class="c" name="Fx" type="range" min="0" max="2" step="0.01" value="0" />
<span>0</span>
</div>
<div class="r 18">
<div class="c m 30">Fy:</div>
<input class="c" name="Fy" type="range" min="0" max="2" step="0.01" value="0" />
<span>0</span>
</div>
<div class="r 18">
<div class="c m 30">a:</div>
<input class="c" name="a" type="range" min="0" max="4" step="0.01" value="1" />
<span>1</span>
</div>
<div class="r 18">
<div class="c m 30">b:</div>
<input class="c" name="b" type="range" min="0" max="4" step="0.01" value="1" />
<span>1</span>
</div>
<div class="r 18">
<div class="c m 30">scale:</div>
<input class="c" name="scale" type="range" min="0" max="20" step="0.01" value="1" />
<span>1</span>
</div>
<div class="r 18">
<div class="c m 30">FOV x:</div>
<input class="c" name="x" type="range" min="0" max="2" step="0.01" value="1" />
<span>1</span>
</div>
<div class="r 18">
<div class="c m 30">FOV y:</div>
<input class="c" name="y" type="range" min="0" max="2" step="0.01" value="1" />
<span>1</span>
</div>
</div>
</div>
</section>
<footer> <a href="https://github.com/publiclab/image-sequencer">View on GitHub</a> </footer>
</div>
<script type="text/javascript">
window.onload = function() {
sequencer = ImageSequencer();
var image = document.querySelector('#fisheye');
sequencer.setUI({
onComplete: function(step){
image.src = step.output;
}
});
sequencer.loadImage('fisheye','images/grid.png',function(){
this.addSteps('fisheye-gl').run();
});
var inputs = document.querySelectorAll('input[type="range"]')
for(i in inputs)
inputs[i].oninput = function(e) {
e.target.nextSibling.nextSibling.innerHTML = e.target.value;
sequencer.images.fisheye.steps[1].options[e.target.name] = e.target.value;
sequencer.run(1);
}
document.querySelector('#file').onchange = function(e) {
var file = e.target.files[0];
if(!file) return;
var reader = new FileReader();
reader.onload = function() {
sequencer.images.fisheye.steps[0].output.src = reader.result;
sequencer.run(0);
}
reader.readAsDataURL(file);
}
}
</script>
</body>
</html>

1
examples/images/IS-QR.js Normal file

File diff suppressed because one or more lines are too long

BIN
examples/images/IS-QR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 621 B

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
examples/images/load.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
examples/images/monarch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

View File

Before

Width:  |  Height:  |  Size: 288 B

After

Width:  |  Height:  |  Size: 288 B

BIN
examples/images/red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
examples/images/test.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

File diff suppressed because one or more lines are too long

BIN
examples/images/tulips.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

223
examples/index.html Normal file
View File

@@ -0,0 +1,223 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<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">
<title>Image Sequencer</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<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>
<!-- 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="lib/scrollToTop.js"></script>
<script src="../node_modules/selectize/dist/js/standalone/selectize.min.js"></script>
</head>
<body>
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.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: -->
<link href="./selectize.default.css" rel="stylesheet">
<link rel="stylesheet" href="demo.css">
<div class="container-fluid">
<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
creates a new image at each step in a sequence.
<a href="https://publiclab.org/image-sequencer">Learn more</a>
</p>
<p>
Open Source
<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>
</p>
</header>
<div id="dropzone" class="dropzone">
<p>
<i>Select or drag in an image to start!</i>
</p>
<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="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>
</center>
</div>
<section id="steps" class="row">
<div id="load-image"></div>
</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;">
</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>
</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>
</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>
</footer>
<button id="move-up"><i class="fa fa-arrow-circle-o-up"></i></button>
<script type="text/javascript">
$(function() {
var sequencer;
})
</script>
</body>
</html>

39
examples/lib/cache.js Normal file
View File

@@ -0,0 +1,39 @@
var setupCache = function() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js', { scope: '/examples/' })
.then(function(registration) {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
console.log(installingWorker)
if (installingWorker.state === 'installed') {
location.reload();
}
}
console.log('Registration successful, scope is:', registration.scope);
})
.catch(function(error) {
console.log('Service worker registration failed, error:', error);
});
}
if ('serviceWorker' in navigator) {
caches.keys().then(function(cacheNames) {
cacheNames.forEach(function(cacheName) {
$("#clear-cache").append(" " + cacheName);
});
});
}
$("#clear-cache").click(function() {
if ('serviceWorker' in navigator) {
caches.keys().then(function(cacheNames) {
cacheNames.forEach(function(cacheName) {
caches.delete(cacheName);
});
});
}
location.reload();
});
}
module.exports = setupCache;

View File

@@ -0,0 +1,92 @@
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";
function onLoad() {
importStepsFromUrlHash();
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");
if (hash) {
_sequencer.importString(hash);
_sequencer.run({ index: 0 });
}
urlHash.setUrlHashParameter("steps", sequencer.toString());
}
function selectNewStepUi() {
var m = $(addStepSel + " select").val();
if(!m) m = arguments[0];
$(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());
//disable save-sequence button if all steps are removed
handleSaveSequence();
}
function addStepUi() {
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
* length - 2 of the drawarray
*/
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"];
}
_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");
//enable save-sequence button if disabled initially
handleSaveSequence();
// add to URL hash too
urlHash.setUrlHashParameter("steps", _sequencer.toString())
}
function handleSaveSequence(){
var stepCount=sequencer.steps.length;
if(stepCount<2)
$(" #save-seq").prop("disabled", true);
else
$(" #save-seq").prop("disabled", false);
}
return {
onLoad: onLoad,
importStepsFromUrlHash: importStepsFromUrlHash,
selectNewStepUi: selectNewStepUi,
removeStepUi: removeStepUi,
addStepUi: addStepUi
}
}
module.exports = DefaultHtmlSequencerUi;

View File

@@ -0,0 +1,344 @@
// Set the UI in sequencer. This Will generate HTML based on
// Image Sequencer events :
// onSetup : Called every time a step is added
// onDraw : Called every time a step starts draw
// onComplete : Called every time a step finishes drawing
// onRemove : Called everytime a step is removed
// The variable 'step' stores useful data like input and
// output values, step information.
// See documetation for more details.
var intermediateHtmlStepUi = require('./intermediateHtmlStepUi.js');
var urlHash = require('./urlHash.js');
var _ = require('lodash');
var mapHtmlTypes = require('./mapHtmltypes');
function DefaultHtmlStepUi(_sequencer, options) {
options = options || {};
var stepsEl = options.stepsEl || document.querySelector("#steps");
var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep";
function onSetup(step, stepOptions) {
if (step.options && step.options.description)
step.description = step.options.description;
step.ui =
'\
<div class="container-fluid step-container">\
<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>\
<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>\
<form class="input-form">\
<div class="panel-body cal collapse in">\
<div class="row step">\
<div class="col-md-4 details container-fluid">\
<div class="cal collapse in"><p>' +
'<i>' + (step.description || "") + '</i>' +
'</p></div>\
</div>\
<div class="col-md-8 cal collapse in step-column">\
<div class="load load-spin" style="display:none;"><i class="fa fa-circle-o-notch fa-spin"></i></div>\
<div class="step-image">\
<a class="cal collapse in"><img class="img-thumbnail step-thumbnail"/></a>\
</div>\
</div>\
</div>\
</div>\
<div class="panel-footer cal collapse in"></div>\
</form>\
</div>\
</div>';
var tools =
'<div class="trash">\
<button confirm="Are you sure?" class="remove btn btn-default btn-xs">\
<i class="fa fa-trash"></i>\
</button>\
</div>';
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");
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
var inputs = _sequencer.modulesInfo(step.name).inputs;
var outputs = _sequencer.modulesInfo(step.name).outputs;
var merged = Object.assign(inputs, outputs); // combine outputs w inputs
for (var paramName in merged) {
var isInput = inputs.hasOwnProperty(paramName);
var html = "";
var inputDesc = isInput ? mapHtmlTypes(inputs[paramName]) : {};
if (!isInput) {
html += '<span class="output"></span>';
} 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 += "</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.type.toLowerCase() == "range") {
html +=
'"min="' +
inputDesc.min +
'"max="' +
inputDesc.max +
'"step="' +
(inputDesc.step ? inputDesc.step : 1)+ '">' + '<span>' + paramVal + '</span>';
}
else html += '">';
}
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='" +
paramName +
"'>" +
description +
"</label>\
" +
html +
"\
</div>";
step.ui.querySelector("div.details").appendChild(div);
}
$(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(
'<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>'
);
}
if (step.name != "load-image") {
step.ui
.querySelector("div.trash-container")
.prepend(
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) });
// 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);
} else {
stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]);
}
}
else {
$("#load-image").append(step.ui);
}
$(step.ui.querySelector(".toggle")).on("click", () => {
$(step.ui.querySelector('.toggleIcon')).toggleClass('rotated');
$(step.ui.querySelectorAll(".cal")).collapse('toggle');
});
$(step.imgElement).on("mousemove", _.debounce(() => imageHover(step), 150));
function saveOptions(e) {
e.preventDefault();
if (optionsChanged){
$(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();
});
_sequencer.run({ index: step.index - 1 });
// modify the url hash
urlHash.setUrlHashParameter("steps", _sequencer.toString())
// disable the save button
$(step.ui.querySelector('.btn-save')).prop('disabled', true);
optionsChanged = false;
changedInputs = 0;
}
}
function handleInputValueChange(currentValue, initValue, hasChangedBefore) {
var inputChanged = !(isNaN(initValue) || isNaN(currentValue) ? currentValue === initValue : currentValue - initValue === 0);
changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0;
optionsChanged = changedInputs > 0;
$(step.ui.querySelector('.btn-save')).prop('disabled', !optionsChanged);
return inputChanged;
}
var
changedInputs = 0,
optionsChanged = false;
$(step.ui.querySelector('.input-form')).on('submit', saveOptions);
$(step.ui.querySelectorAll('.target')).each(function(i, input) {
$(input)
.data('initValue', $(input).val())
.data('hasChangedBefore', false)
.on('input', function() {
$(this)
.focus()
.data('hasChangedBefore',
handleInputValueChange(
$(this).val(),
$(this).data('initValue'),
$(this).data('hasChangedBefore')
)
)
})
})
$('input[type="range"]').on('input', function() {
$(this).next().html($(this).val());
})
}
function onDraw(step) {
$(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.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;
}
// TODO: use a generalized version of this
function fileExtension(output) {
return output.split("/")[1].split(";")[0];
}
for (let index = 0; index < step.linkElements.length; index++) {
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)) {
var inputs = _sequencer.modulesInfo(step.name).inputs;
var outputs = _sequencer.modulesInfo(step.name).outputs;
for (var i in inputs) {
if (step.options[i] !== undefined) {
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")
$(step.ui.querySelector('div[name="' + i + '"] select'))
.val(step.options[i])
.data('initValue', step.options[i]);
}
}
for (var i in outputs) {
if (step[i] !== undefined)
$(step.ui.querySelector('div[name="' + i + '"] input'))
.val(step[i]);
}
}
}
function imageHover(step){
var img = $(step.imgElement);
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);
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;
});
}
function onRemove(step) {
step.ui.remove();
$("#steps .step-container:nth-last-child(1) .insert-step").prop('disabled',true);
$('div[class*=imgareaselect-]').remove();
}
function getPreview() {
return step.imgElement;
}
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");
$('body').append(notification);
}
$('#'+id).fadeIn(500).delay(200).fadeOut(500);
}
return {
getPreview: getPreview,
onSetup: onSetup,
onComplete: onComplete,
onRemove: onRemove,
onDraw: onDraw,
notify: notify,
imageHover: imageHover
}
}
if(typeof window === "undefined"){
module.exports={
DefaultHtmlStepUi: DefaultHtmlStepUi
}
}
module.exports = DefaultHtmlStepUi;

View File

@@ -0,0 +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);
}
});
}
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

@@ -0,0 +1,163 @@
var urlHash = require('./urlHash.js'),
insertPreview = require('./insertPreview.js');
function IntermediateHtmlStepUi(_sequencer, step, options) {
function stepUI() {
return '<div class="row insertDiv collapse">\
<section class="panel panel-primary .insert-step">\
<button class="btn btn-default close-insert-box"><i class="fa fa-times" aria-hidden="true"></i> Close</button>\
<div class="form-inline">\
<div class="panel-body">\
<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>\
</div>\
<div class="row center-align">\
<div class="col-md-8">\
<select class="insert-step-select">\
<!-- 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 insert-save-btn add-step-btn" name="add">Add Step</button>\
<div>\
</div>\
</div>\
</div>\
</section>\
</div>';
}
function selectNewStepUi() {
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);
}
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)})
}
else {
$(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")
if ($(step.ui.querySelector('.insertDiv')).length > 0){
toggleDiv();
}
else {
step.ui
.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(){})});
var insertStepSelect = $(step.ui.querySelector('.insert-step-select'));
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>"
);
}
insertStepSelect.selectize({
sortField: 'text'
});
$(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 () {
$(this).parent().find('.radio').removeClass('selected');
$(this).addClass('selected');
newStep = $(this).attr('data-value');
$(step.ui.querySelector('.insert-step-select')).val(newStep);
selectNewStepUi();
insert(id);
$(this).removeClass('selected');
});
insertStepSelect.on('change', selectNewStepUi);
$(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;
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"];
}
_sequencer
.insertSteps(id + 1, newStepName).run({ index: id });
// add to URL hash too
urlHash.setUrlHashParameter("steps", _sequencer.toString());
}
return {
insertStep
}
}
module.exports = IntermediateHtmlStepUi;

View File

@@ -0,0 +1,28 @@
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;
}
var response = inputInfo;
response.type = htmlType;
return response;
}
module.exports = mapHtmlTypes;

49
examples/lib/urlHash.js Normal file
View File

@@ -0,0 +1,49 @@
function getUrlHashParameter(param) {
var params = getUrlHashParameters();
return params[param];
}
function getUrlHashParameters() {
var sPageURL = window.location.hash;
if (sPageURL) sPageURL = sPageURL.split('#')[1];
var pairs = sPageURL.split('&');
var object = {};
pairs.forEach(function(pair, i) {
pair = pair.split('=');
if (pair[0] != '') object[pair[0]] = pair[1];
});
return object;
}
// accepts an object like { paramName: value, paramName1: value }
// and transforms to: url.com#paramName=value&paramName1=value
function setUrlHashParameters(params) {
var keys = Object.keys(params);
var values = Object.values(params);
var pairs = [];
keys.forEach(function(key, i) {
if (key != '') pairs.push(keys[i] + '=' + values[i]);
});
var hash = pairs.join('&');
window.location.hash = hash;
}
function setUrlHashParameter(param, value) {
var params = getUrlHashParameters();
params[param] = value;
setUrlHashParameters(params);
}
module.exports = {
getUrlHashParameter: getUrlHashParameter,
setUrlHashParameter: setUrlHashParameter,
getUrlHashParameters: getUrlHashParameters,
setUrlHashParameters: setUrlHashParameters
}

21
examples/manifest.json Normal file
View File

@@ -0,0 +1,21 @@
{
"short_name": "IS",
"name": "Image Sequencer",
"icons": [
{
"src": "../icons/ic_192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "../icons/ic_512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/examples/#steps=",
"background_color": "#428bca",
"display": "standalone",
"scope": "/examples/",
"theme_color": "#428bca"
}

View File

@@ -9,7 +9,7 @@
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="../node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="../dist/image-sequencer.css" rel="stylesheet">
<link href="demo-old.css" rel="stylesheet">
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
@@ -33,7 +33,7 @@
<div class="panels">
<div class="panel ismod-image-select" style="display:flex;justify-content:center">
<img src="replace.jpg" id="pencils" style="cursor:pointer">
<img src="images/replace.jpg" id="pencils" style="cursor:pointer">
</div>
</div>

View File

@@ -0,0 +1,403 @@
/**
* selectize.default.css (v0.12.6) - Default Theme
* Copyright (c) 20132015 Brian Reavis & contributors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*
* @author Brian Reavis <brian@thirdroute.com>
*/
.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
visibility: visible !important;
background: #f2f2f2 !important;
background: rgba(0, 0, 0, 0.06) !important;
border: 0 none !important;
-webkit-box-shadow: inset 0 0 12px 4px #fff;
box-shadow: inset 0 0 12px 4px #fff;
}
.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
content: '!';
visibility: hidden;
}
.selectize-control.plugin-drag_drop .ui-sortable-helper {
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.selectize-dropdown-header {
position: relative;
padding: 5px 8px;
border-bottom: 1px solid #d0d0d0;
background: #f8f8f8;
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
}
.selectize-dropdown-header-close {
position: absolute;
right: 8px;
top: 50%;
color: #303030;
opacity: 0.4;
margin-top: -12px;
line-height: 20px;
font-size: 20px !important;
}
.selectize-dropdown-header-close:hover {
color: #000000;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup {
border-right: 1px solid #f2f2f2;
border-top: 0 none;
float: left;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
border-right: 0 none;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup:before {
display: none;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup-header {
border-top: 0 none;
}
.selectize-control.plugin-remove_button [data-value] {
position: relative;
padding-right: 24px !important;
}
.selectize-control.plugin-remove_button [data-value] .remove {
z-index: 1;
/* fixes ie bug (see #392) */
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 17px;
text-align: center;
font-weight: bold;
font-size: 12px;
color: inherit;
text-decoration: none;
vertical-align: middle;
display: inline-block;
padding: 2px 0 0 0;
border-left: 1px solid #0073bb;
-webkit-border-radius: 0 2px 2px 0;
-moz-border-radius: 0 2px 2px 0;
border-radius: 0 2px 2px 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.selectize-control.plugin-remove_button [data-value] .remove:hover {
background: rgba(0, 0, 0, 0.05);
}
.selectize-control.plugin-remove_button [data-value].active .remove {
border-left-color: #00578d;
}
.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
background: none;
}
.selectize-control.plugin-remove_button .disabled [data-value] .remove {
border-left-color: #aaaaaa;
}
.selectize-control.plugin-remove_button .remove-single {
position: absolute;
right: 0;
top: 0;
font-size: 23px;
}
.selectize-control {
position: relative;
}
.selectize-dropdown,
.selectize-input,
.selectize-input input {
color: #303030;
font-family: inherit;
font-size: 18px;
line-height: 18px;
-webkit-font-smoothing: inherit;
}
.selectize-input,
.selectize-control.single .selectize-input.input-active {
background: #fff;
cursor: text;
display: inline-block;
}
.selectize-input {
border: 1px solid #d0d0d0;
padding: 10px 0px;
display: inline-block;
width: 24vw;
overflow: hidden;
position: relative;
z-index: 1;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.selectize-control.multi .selectize-input.has-items {
padding: 5px 8px 2px;
}
.selectize-input.full {
background-color: #fff;
}
.selectize-input.disabled,
.selectize-input.disabled * {
cursor: default !important;
}
.selectize-input.focus {
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
}
.selectize-input.dropdown-active {
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
}
.selectize-input > * {
vertical-align: baseline;
display: -moz-inline-stack;
display: inline-block;
zoom: 1;
*display: inline;
}
.selectize-control.multi .selectize-input > div {
cursor: pointer;
margin: 0 3px 3px 0;
padding: 2px 6px;
background: #1da7ee;
color: #fff;
border: 1px solid #0073bb;
}
.selectize-control.multi .selectize-input > div.active {
background: #92c836;
color: #fff;
border: 1px solid #00578d;
}
.selectize-control.multi .selectize-input.disabled > div,
.selectize-control.multi .selectize-input.disabled > div.active {
color: #ffffff;
background: #d2d2d2;
border: 1px solid #aaaaaa;
}
.selectize-input > input {
display: inline-block !important;
padding: 0 !important;
min-height: 0 !important;
max-height: none !important;
max-width: 100% !important;
margin: 0 1px !important;
text-indent: 0 !important;
border: 0 none !important;
background: none !important;
line-height: inherit !important;
-webkit-user-select: auto !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
.selectize-input > input::-ms-clear {
display: none;
}
.selectize-input > input:focus {
outline: none !important;
}
.selectize-input::after {
content: ' ';
display: block;
clear: left;
}
.selectize-input.dropdown-active::before {
content: ' ';
display: block;
position: absolute;
background: #f0f0f0;
height: 1px;
bottom: 0;
left: 0;
right: 0;
}
.selectize-dropdown {
position: absolute;
z-index: 10;
border: 1px solid #d0d0d0;
background: #fff;
margin: -1px 0 0 0;
border-top: 0 none;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-webkit-border-radius: 0 0 3px 3px;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
}
.selectize-dropdown [data-selectable] {
cursor: pointer;
overflow: hidden;
}
.selectize-dropdown [data-selectable] .highlight {
background: rgba(125, 168, 208, 0.2);
-webkit-border-radius: 1px;
-moz-border-radius: 1px;
border-radius: 1px;
}
.selectize-dropdown .option,
.selectize-dropdown .optgroup-header {
padding: 5px 8px;
}
.selectize-dropdown .option,
.selectize-dropdown [data-disabled],
.selectize-dropdown [data-disabled] [data-selectable].option {
cursor: inherit;
opacity: 0.5;
}
.selectize-dropdown [data-selectable].option {
opacity: 1;
}
.selectize-dropdown .optgroup:first-child .optgroup-header {
border-top: 0 none;
}
.selectize-dropdown .optgroup-header {
color: #303030;
background: #fff;
cursor: default;
}
.selectize-dropdown .active {
background-color: #f5fafd;
color: #495c68;
}
.selectize-dropdown .active.create {
color: #495c68;
}
.selectize-dropdown .create {
color: rgba(48, 48, 48, 0.5);
}
.selectize-dropdown-content {
overflow-y: auto;
overflow-x: hidden;
max-height: 200px;
-webkit-overflow-scrolling: touch;
}
.selectize-control.single .selectize-input,
.selectize-control.single .selectize-input input {
cursor: pointer;
}
.selectize-control.single .selectize-input.input-active,
.selectize-control.single .selectize-input.input-active input {
cursor: text;
}
.selectize-control.single .selectize-input:after {
content: ' ';
display: block;
position: absolute;
top: 50%;
right: 15px;
margin-top: -3px;
width: 0;
height: 0;
border-style: solid;
border-width: 5px 5px 0 5px;
border-color: #808080 transparent transparent transparent;
}
.selectize-control.single .selectize-input.dropdown-active:after {
margin-top: -4px;
border-width: 0 5px 5px 5px;
border-color: transparent transparent #808080 transparent;
}
.selectize-control.rtl.single .selectize-input:after {
left: 15px;
right: auto;
}
.selectize-control.rtl .selectize-input > input {
margin: 0 4px 0 -2px !important;
}
.selectize-control .selectize-input.disabled {
opacity: 0.5;
background-color: #fafafa;
}
.selectize-control.multi .selectize-input.has-items {
padding-left: 5px;
padding-right: 5px;
}
.selectize-control.multi .selectize-input.disabled [data-value] {
color: #999;
text-shadow: none;
background: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.selectize-control.multi .selectize-input.disabled [data-value],
.selectize-control.multi .selectize-input.disabled [data-value] .remove {
border-color: #e6e6e6;
}
.selectize-control.multi .selectize-input.disabled [data-value] .remove {
background: none;
}
.selectize-control.multi .selectize-input [data-value] {
text-shadow: 0 1px 0 rgba(0, 51, 83, 0.3);
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #1b9dec;
background-image: -moz-linear-gradient(top, #1da7ee, #178ee9);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1da7ee), to(#178ee9));
background-image: -webkit-linear-gradient(top, #1da7ee, #178ee9);
background-image: -o-linear-gradient(top, #1da7ee, #178ee9);
background-image: linear-gradient(to bottom, #1da7ee, #178ee9);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1da7ee', endColorstr='#ff178ee9', GradientType=0);
-webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03);
box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03);
}
.selectize-control.multi .selectize-input [data-value].active {
background-color: #0085d4;
background-image: -moz-linear-gradient(top, #008fd8, #0075cf);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#008fd8), to(#0075cf));
background-image: -webkit-linear-gradient(top, #008fd8, #0075cf);
background-image: -o-linear-gradient(top, #008fd8, #0075cf);
background-image: linear-gradient(to bottom, #008fd8, #0075cf);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff008fd8', endColorstr='#ff0075cf', GradientType=0);
}
.selectize-control.single .selectize-input {
-webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8);
box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8);
background-color: #f9f9f9;
background-image: -moz-linear-gradient(top, #fefefe, #f2f2f2);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fefefe), to(#f2f2f2));
background-image: -webkit-linear-gradient(top, #fefefe, #f2f2f2);
background-image: -o-linear-gradient(top, #fefefe, #f2f2f2);
background-image: linear-gradient(to bottom, #fefefe, #f2f2f2);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffefefe', endColorstr='#fff2f2f2', GradientType=0);
}
/* .selectize-control.single .selectize-input,
.selectize-dropdown.single {
border-color: #b8b8b8;
} */
.selectize-dropdown .optgroup-header {
padding-top: 7px;
font-weight: bold;
font-size: 0.85em;
}
.selectize-dropdown .optgroup {
border-top: 1px solid #f0f0f0;
}
.selectize-dropdown .optgroup:first-child {
border-top: 0 none;
}

35
examples/sw.js Normal file
View File

@@ -0,0 +1,35 @@
const staticCacheName = 'image-sequencer-static-v3';
self.addEventListener('install', event => {
console.log('Attempting to install service worker');
});
self.addEventListener('activate', function(e) {
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.filter(function(cacheName){
return cacheName.startsWith('image-sequencer-') &&
cacheName != staticCacheName;
}).map(function(cacheName){
return caches.delete(cacheName);
})
);
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(
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")
cache.put(event.request, response.clone());
return response;
});
});
})
);
});

BIN
icons/ic_144.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
icons/ic_192.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
icons/ic_512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
icons/ic_96.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -1,87 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8">
<title>Image Sequencer</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="dist/image-sequencer.css" rel="stylesheet">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="dist/image-sequencer.js"></script>
<meta http-equiv="refresh" content="0; url=examples/" />
</head>
<body>
<div class="header">
<h1>Image Sequencer</h1>
<h3>
<a href="https://github.com/jywarren/image-sequencer"><i class="fa fa-github"></i></a>
</h3>
</div>
<p style="display:none;" class="spinner"><i class="fa fa-spinner fa-spin"></i></p>
<div class="panels">
<div class="panel ismod-image-select">
<div class="mod-drop">Drag image here</div>
<p class="instructions">Select or drop an image here to begin.</p>
<input id="file-select" type="file" />
</div>
</div>
<div class="mod-new-panel">
<form class="mod-new-panel">
<p class="instructions">Add a new step</p>
<select class="select-module form-control" style="margin-bottom:6px;">
<option value="ndvi-red">NDVI with red filter</option>
<option value="green-channel">Green channel</option>
<option value="plot">Plot with colorbar</option>
<option value="image-threshold">Threshold image</option>
</select>
<p><button class="btn btn-default add-step">Add step</button></p>
</form>
</div>
<div class="log">
<h4>Log</h4>
</div>
<script>
var sequencer;
jQuery(document).ready(function($) {
sequencer = ImageSequencer();
sequencer.loadImage('examples/grid.png');
sequencer.addStep('ndvi-red');
sequencer.addStep('image-threshold');
sequencer.addStep('crop');
//sequencer.addStep('plot');
$('.add-step').click(function(e) {
e.preventDefault();
sequencer.addStep($('.select-module').val());
sequencer.run(sequencer.options.initialImage); // later we might only run this step, if we can fetch the image output from the previous
});
});
</script>
</body>
</html>

96
index.js Normal file → Executable file
View File

@@ -1,11 +1,89 @@
console.log('\x1b[31m%s\x1b[0m',"This is the output of the module");
#!/usr/bin/env node
require('./src/ImageSequencer');
sequencer = ImageSequencer();
sequencer.loadImages({images:{red:'examples/red.jpg'},callback:function(){
sequencer.addSteps(['do-nothing-pix','ndvi-red','invert']);
sequencer.removeSteps(1);
sequencer.insertSteps({
red: [{index: -1, name: 'do-nothing-pix', o:{}}]
sequencer = ImageSequencer({ ui: false });
var fs = require('fs')
var program = require('commander');
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')
function exit(message) {
console.error(message);
process.exit(1);
}
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")
.parse(process.argv);
if (program.saveSequence) saveSequence(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(" ");
// User must input an image.
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.");
});
sequencer.run();
}});
// 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.");
// If there's no user defined output directory, select a default directory.
program.output = program.output || "./output/";
// Set sequencer to log module outputs, if any.
sequencer.setUI({
onComplete: function(step) {
// Get information of outputs.
step.info = sequencer.modulesInfo(step.name);
for (var output in step.info.outputs) {
console.log("[" + program.step + "]: " + output + " = " + step[output]);
}
},
notify: function(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"
);
//Generate the Output Directory
var outputFilename = program.output.split('/').slice(-1)[0];
if (outputFilename.includes('.')) {
// user did give an output filename we have to remove it from dir
program.output = program.output.split('/').slice(0, -1).join('/');
}
else {
outputFilename = null;
}
sequencerSteps(program, sequencer, outputFilename)
});
}

9497
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,14 @@
{
"name": "image-sequencer",
"version": "0.0.1",
"version": "3.0.1",
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
"main": "dist/image-sequencer.js",
"main": "src/ImageSequencer.js",
"scripts": {
"test": "tape test/*.js | tap-spec; browserify test/image-sequencer.js test/chain.js | tape-run --render=\"tap-spec\""
"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/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"
},
"repository": {
"type": "git",
@@ -20,28 +24,58 @@
"url": "https://github.com/publiclab/image-sequencer/issues"
},
"dependencies": {
"bootstrap": "~3.2.0",
"font-awesome": "~4.5.0",
"jquery": "~2",
"urify": "^2.1.0"
"bootstrap": "~3.4.0",
"buffer": "~5.2.1",
"commander": "^2.11.0",
"data-uri-to-buffer": "^2.0.0",
"downloadjs": "^1.4.7",
"fisheyegl": "^0.1.2",
"font-awesome": "~4.7.0",
"geotiff": "^1.0.0-beta.6",
"get-pixels": "~3.3.0",
"gifshot": "^0.4.5",
"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",
"jquery": "^3.3.1",
"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",
"qrcode": "^1.3.3",
"readline-sync": "^1.4.7",
"save-pixels": "~2.3.4",
"selectize": "^0.12.6",
"urify": "^2.1.1"
},
"devDependencies": {
"base64-stream": "~0.1.3",
"browserify": "13.0.0",
"buffer": "~5.0.2",
"get-pixels": "~3.3.0",
"grunt": "^0.4.5",
"base64-img": "^1.0.4",
"browserify": "16.2.3",
"grunt": "^1.0.3",
"grunt-browser-sync": "^2.2.0",
"grunt-browserify": "^5.0.0",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-watch": "^0.6.1",
"image-filter-core": "~1.0.0",
"image-filter-threshold": "~1.0.0",
"matchdep": "^0.3.0",
"plotly.js": "~1.21.2",
"save-pixels": "~2.3.4",
"tap-spec": "^4.1.1",
"tape": ">=4.7.0",
"tape-run": "^3.0.0"
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-uglify-es": "^3.3.0",
"grunt-contrib-watch": "^1.1.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",
"looks-same": "^7.0.0",
"matchdep": "^2.0.0",
"tap-spec": "^5.0.0",
"tape": "^4.9.2",
"tape-run": "^5.0.0",
"uglify-es": "^3.3.7"
},
"homepage": "https://github.com/publiclab/image-sequencer"
"homepage": "https://sequencer.publiclab.org",
"bin": {
"sequencer": "./index.js"
}
}

View File

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

View File

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

8
spec/helpers/reporter.js Normal file
View File

@@ -0,0 +1,8 @@
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
jasmine.getEnv().clearReporters(); // remove default reporter logs
jasmine.getEnv().addReporter(new SpecReporter({ // add jasmine-spec-reporter
spec: {
displayPending: true
}
}));

View File

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

View File

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

11
spec/support/jasmine.json Normal file
View File

@@ -0,0 +1,11 @@
{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
],
"stopSpecOnExpectationFailure": false,
"random": true
}

40
spec/urlHash.spec.js Normal file
View File

@@ -0,0 +1,40 @@
describe('URL manipulation methods', function() {
var UrlHash = require('../examples/lib/urlHash')
var urlHash;
var params = {
module: 'brightness',
brightness: 50
}
beforeEach(()=>{
urlHash = UrlHash
spyOn(urlHash,'getUrlHashParameters')
spyOn(urlHash,'getUrlHashParameter')
spyOn(urlHash,'setUrlHashParameters')
spyOn(urlHash,'setUrlHashParameter')
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()
})
it('gets url hash param from params object', function() {
expect(urlHash.getUrlHashParameter).toHaveBeenCalledWith('module')
})
it('accepts param object and sets url hash params', function() {
expect(urlHash.setUrlHashParameters).toHaveBeenCalledWith(params)
})
it('accepts param key-value pair and sets url hash params', function() {
expect(urlHash.setUrlHashParameter).toHaveBeenCalledWith('module','brightness')
})
})

View File

@@ -1,33 +1,5 @@
function AddStep(ref, image, name, o) {
function addStep(image, name, o_) {
ref.log('\x1b[36m%s\x1b[0m','adding step \"' + name + '\" to \"' + image + '\".');
var o = ref.copy(o_);
o.id = ref.options.sequencerCounter++; //Gives a Unique ID to each step
o.name = o_.name || name;
o.selector = o_.selector || 'ismod-' + name;
o.container = o_.container || ref.options.selector;
o.image = image;
var module = ref.modules[name].call(ref.images,o);
ref.images[image].steps.push(module);
function defaultSetupModule() {
if (ref.options.ui && ref.options.ui!="none") module.options.ui = ref.options.ui({
selector: o.selector,
title: module.options.title,
id: o.id
});
}
if (module.hasOwnProperty('setup')) module.setup(); // add a default UI, unless the module has one specified
else defaultSetupModule.apply(module); // run default setup() in scope of module (is this right?)
// tell the UI that a step has been added.
return true;
}
addStep(image, name, o);
// add steps to the sequencer
function AddStep(_sequencer, name, o) {
return require('./InsertStep')(_sequencer,-1,name,o);
}
module.exports = AddStep;

58
src/CliUtils.js Normal file
View File

@@ -0,0 +1,58 @@
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();
});
else callback()
});
};
// Takes an array of steps and checks if they are valid steps for the sequencer.
function validateSteps(steps, sequencer) {
// Assume all are valid in the beginning.
var valid = true;
steps.forEach(function(step) {
// If any step in the array is not valid (not a property of modulesInfo), set valid to false.
if (!sequencer.modulesInfo().hasOwnProperty(step)) {
valid = false;
}
});
// Return valid. (If all of the steps are valid properties, valid will have remained true).
return valid;
}
//Takes config and options object and checks if all the keys exist in config
function validateConfig(config_, options_) {
options_ = Object.keys(options_);
if (
(function() {
for (var input in options_) {
if (!config_[options_[input]]) {
console.error(
"\x1b[31m%s\x1b[0m",
`Options Object does not have the required details "${
options_[input]
}" not specified. Fallback case activated`
);
return false;
}
}
})() == false
)
return false;
else return true;
}
module.exports = exports = {
makedir: makedir,
validateSteps: validateSteps,
validateConfig: validateConfig
}

69
src/ExportBin.js Executable file
View File

@@ -0,0 +1,69 @@
var fs = require('fs');
var getDirectories = function(rootDir, cb) {
fs.readdir(rootDir, function(err, files) {
var dirs = [];
if (typeof (files) == "undefined" || files.length == 0) {
cb(dirs);
return [];
}
for (var index = 0; index < files.length; ++index) {
var file = files[index];
if (file[0] !== '.') {
var filePath = rootDir + '/' + file;
fs.stat(filePath, function(err, stat) {
if (stat.isDirectory()) {
dirs.push(this.file);
}
if (files.length === (this.index + 1)) {
return cb(dirs);
}
}.bind({ index: index, file: file }));
}
}
});
}
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 + "/";
if (ref.options.inBrowser) return false;
fs.access(dir, function(err) {
if (err) console.error(err)
});
if (filename && basic) {
var steps = ref.steps;
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(dir + filename, buffer, function() { });
}
else {
getDirectories(dir, function(dirs) {
var num = 1;
for (var d in dirs) {
if (dirs[d].match(/^sequencer(.*)$/) == null) continue;
var n = parseInt(dirs[d].match(/^sequencer(.*)$/)[1]);
num = (n >= num) ? (n + 1) : num;
}
fs.mkdir(dir + 'sequencer' + num, function() {
var root = dir + 'sequencer' + num + '/';
var steps = ref.steps;
if (basic) {
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() { });
}
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() { });
}
}
});
});
}
}

View File

@@ -24,42 +24,19 @@ function copy(a) {
}
function formatInput(args,format,images) {
images = [];
for (var image in this.images) {
images.push(image);
}
var json_q = {};
var format_i = format;
if (format == "+")
format = ['o_string_a', 'string_a', 'o_object'];
format = ['string_a', 'o_object'];
else if (format == "-")
format = ['o_string_a', 'number_a'];
format = ['number_a'];
else if (format == "^")
format = ['o_string_a', 'number', 'string', 'o_object'];
format = ['number', 'string', 'o_object'];
else if (format == "r")
format = ['o_string_a', 'o_number'];
format = ['o_number'];
else if (format == "l")
format = ['o_string','string','o_function'];
/*
formats:
addSteps :: o_image_a, name_a, o_o
o_string_a, string_a, o_object => { image: [{name,o}] }
removeSteps :: o_image_a, index_a
o_string_a, number_a => { image: [index] }
insertSteps :: o_image_a, index, name, o_o
o_string_a, number, string, o_object => { image: [{index,name,o}] }
run :: o_image_a, o_from
o_string_a, o_number => { image: index }
loadImages :: image, src, o_function
string, string, o_function => { images: [{image:src}], callback }
optionals:
image: o_string_a
options: o_object
from: o_number
callback: o_function
*/
format = ['string','o_function'];
if(format[format.length-1] == "o_object") {
if(objTypeOf(args[args.length-1]) != "Object")
@@ -74,90 +51,56 @@ function formatInput(args,format,images) {
args.push(function(){});
}
if(format[0] == "o_string_a") {
if(args.length == format.length - 1) {
var insert = false;
for (var i in args) {
if (format[parseInt(i)+1].includes( typeof(getPrimitive(args[i])) )){
insert = true;
}
else {insert = false; break;}
}
if(insert)
args.splice(0,0,copy(images));
}
}
else if (format[0] == "o_string" && format_i == "l" && args.length == 2) {
if (typeof(args[0]) == "string") {
var identifier = "image";
var number = 1;
while (this.images.hasOwnProperty(identifier+number)) number++;
args.splice(0,0,identifier+number);
}
}
if(args.length == format.length) {
if(args.length == format.length) {//making of arrays
for (var i in format) {
if (format[i].substr(format[i].length-2,2)=="_a")
args[i] = makeArray(args[i]);
}
}
if (args.length == 1) {
json_q = copy(args[0]);
if(!(format_i == "r" || format_i == "l")) {
for (var img in json_q)
json_q[img] = makeArray(json_q[img]);
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]);
}
}
else if (format_i == "r") {
for (var img in args[0]) json_q[args[0][img]] = args[1];
else if (format_i == "r" ) {
for (var img in args[0]) json_q = {0:args[0]};
}
else if (format_i == "l") {
json_q = {
images: {},
callback: args[2]
image: args[0],
callback: args[1]
}
json_q.images[args[0]] = args[1];
}
else {
for (var img in args[0]) {
var image = args[0][img];
json_q[image] = [];
json_q = [];
if(format_i == "+") {
for(var s in args[1]) {
json_q[image].push({
name: args[1][s],
o: args[2]
for(var s in args[0]) {
json_q.push({
name: args[0][s],
o: args[1]
});
}
}
if(format_i == "-") {
json_q[image] = args[1];
}
if(format_i == "^") {
var size = this.images[image].steps.length;
var index = args[1];
var size = this.steps.length;
var index = args[0];
index = (index==size)?index:index%size;
if (index<0) index += size+1;
json_q[image].push({
json_q.push({
index: index,
name: args[2],
o: args[3]
name: args[1],
o: args[2]
});
}
}
}
if(format_i == "l") {
json_q.loadedimages = [];
for (var i in json_q.images) json_q.loadedimages.push(i);
}
return json_q;
}

View File

@@ -1,29 +1,30 @@
if (typeof window !== 'undefined') {window.$ = window.jQuery = require('jquery'); 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;
options = options || {};
options.inBrowser = options.inBrowser || isBrowser;
// if (options.inBrowser) options.ui = options.ui || require('./UserInterface');
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)
function objTypeOf(object) {
return Object.prototype.toString.call(object).split(" ")[1].slice(0, -1)
}
function log(color,msg) {
if(options.ui!="none") {
if(arguments.length==1) console.log(arguments[0]);
else if(arguments.length==2) console.log(color,msg);
function log(color, msg) {
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 (!typeof (a) == "object") return a;
if (objTypeOf(a) == "Array") return a.slice();
if (objTypeOf(a) == "Object") {
var b = {};
var b = {};
for (var v in a) {
b[v] = copy(a[v]);
}
@@ -33,133 +34,385 @@ ImageSequencer = function ImageSequencer(options) {
}
function makeArray(input) {
return (objTypeOf(input)=="Array")?input:[input];
return (objTypeOf(input) == "Array") ? input : [input];
}
var image,
steps = [],
modules = require('./Modules'),
formatInput = require('./FormatInput'),
images = {},
inputlog = [];
steps = [],
modules = require('./Modules'),
sequences = require('./SavedSequences.json'),
formatInput = require('./FormatInput'),
inputlog = [],
events = require('./ui/UserInterface')(),
fs = require('fs');
if (options.inBrowser) {
for (o in sequencer) {
modules[o] = sequencer[o];
}
sequences = JSON.parse(window.localStorage.getItem('sequences'));
if (!sequences) {
sequences = {};
window.localStorage.setItem('sequences', JSON.stringify(sequences));
}
}
// if in browser, prompt for an image
// if (options.imageSelect || options.inBrowser) addStep('image-select');
// else if (options.imageUrl) loadImage(imageUrl);
function addSteps(){
const this_ = (this.name == "ImageSequencer")?this:this.sequencer;
var args = (this.name == "ImageSequencer")?[]:[this.images];
function addSteps() {
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,"+");
inputlog.push({method:"addSteps", json_q:copy(json_q)});
for (var i in json_q)
for (var j in json_q[i])
require("./AddStep")(this_,i,json_q[i][j].name,json_q[i][j].o);
for (var arg in arguments) { args.push(copy(arguments[arg])); }
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);
return this;
}
function removeStep(image,index) {
function removeStep(ref, index) {
//remove the step from images[image].steps and redraw remaining images
if(index>0) {
log('\x1b[31m%s\x1b[0m',"Removing "+index+" from "+image);
images[image].steps.splice(index,1);
if (index > 0) {
//var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
thisStep = ref.steps[index];
thisStep.UI.onRemove(thisStep.options.step);
ref.steps.splice(index, 1);
}
//tell the UI a step has been removed
}
function removeSteps(image,index) {
var run = {}, indices;
const this_ = (this.name == "ImageSequencer")?this:this.sequencer;
var args = (this.name == "ImageSequencer")?[]:[this.images];
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)});
for (var img in json_q) {
indices = json_q[img].sort(function(a,b){return b-a});
run[img] = indices[indices.length-1];
for (var i in indices)
removeStep(img,indices[i]);
}
// this.run(run); // This is creating problems
return this;
}
function insertSteps(image, index, name, o) {
var run = {};
const this_ = (this.name == "ImageSequencer")?this:this.sequencer;
var args = (this.name == "ImageSequencer")?[]:[this.images];
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)});
for (var img in json_q) {
var details = json_q[img];
details = details.sort(function(a,b){return b.index-a.index});
for (var i in details)
require("./InsertStep")(this_,img,details[i].index,details[i].name,details[i].o);
run[img] = details[details.length-1].index;
}
// this.run(run); // This is Creating issues
return this;
}
function run(t_image,t_from) {
log('\x1b[32m%s\x1b[0m',"Running the Sequencer!");
const this_ = (this.name == "ImageSequencer")?this:this.sequencer;
var args = (this.name == "ImageSequencer")?[]:[this.images];
function removeSteps() {
var indices;
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = [];
for (var arg in arguments) args.push(copy(arguments[arg]));
var callback = function() {};
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]);
return this;
}
function insertSteps() {
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 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;
}
// Config is an object which contains the runtime configuration like progress bar
// information and index from which the sequencer should run
function run(config) {
var progressObj, index = 0;
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'];
}
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")
callback = args.splice(arg,1)[0];
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);
require('./Run')(this_, json_q, callback, index, progressObj);
return true;
}
function loadImages() {
var args = [];
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");
inputlog.push({method:"loadImages", json_q:copy(json_q)});
var loadedimages = this.copy(json_q.loadedimages);
for (var i in json_q.images)
require('./LoadImage')(this,i,json_q.images[i])
json_q.callback();
return {
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) });
var ret = {
name: "ImageSequencer Wrapper",
sequencer: this,
addSteps: this.addSteps,
removeSteps: this.removeSteps,
insertSteps: this.insertSteps,
run: this.run,
images: loadedimages
UI: this.UI,
setUI: this.setUI
};
function loadPrevSteps(ref){
if(prevSteps.length!=0){
ref.addSteps(prevSteps)
prevSteps=[];
}
}
require('./ui/LoadImage')(sequencer, "image", json_q.image, function() {
loadPrevSteps(sequencer);
json_q.callback.call(ret);
});
}
function replaceImage(selector,steps,options) {
function replaceImage(selector, steps, options) {
options = options || {};
return require('./ReplaceImage')(this,selector,steps);
options.callback = options.callback || function() { };
return require('./ReplaceImage')(this, selector, steps, options);
}
//returns the steps added
function getSteps(){
return this.steps;
}
function setUI(UI) {
this.events = require('./ui/UserInterface')(UI);
}
var exportBin = function(dir, basic, filename) {
return require('./ExportBin')(dir, this, basic, filename);
}
function modulesInfo(name) {
var modulesdata = {}
if (name == "load-image") return {};
if (arguments.length == 0) {
for (var modulename in this.modules) {
modulesdata[modulename] = modules[modulename][1];
}
for (var sequencename in this.sequences) {
modulesdata[sequencename] = { name: sequencename, steps: this.sequences[sequencename] };
}
}
else {
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) {
return this;
} else if (Array.isArray(options)) {
// contains the array of module and info
this.modules[name] = options;
} else if (options.func && options.info) {
// passed in options object
this.modules[name] = [
options.func, options.info
];
} else if (options.path && !this.inBrowser) {
// load from path(only in node)
const module = [
require(`${options.path}/Module.js`),
require(`${options.path}/info.json`)
];
this.modules[name] = module;
}
return this;
}
function saveNewModule(name, path) {
if (options.inBrowser) {
// Not for browser context
return;
}
var mods = fs.readFileSync('./src/Modules.js').toString();
mods = mods.substr(0, mods.length - 1) + " '" + name + "': require('" + path + "'),\n}";
fs.writeFileSync('./src/Modules.js', mods);
}
function saveSequence(name, sequenceString) {
const sequence = stringToJSON(sequenceString);
// Save the given sequence string as a module
if (options.inBrowser) {
// Inside the browser we save the meta-modules using the Web Storage API
var sequences = JSON.parse(window.localStorage.getItem('sequences'));
sequences[name] = sequence;
window.localStorage.setItem('sequences', JSON.stringify(sequences));
}
else {
// In node we save the sequences in the json file SavedSequences.json
var sequences = require('./SavedSequences.json');
sequences[name] = sequence;
fs.writeFileSync('./src/SavedSequences.json', JSON.stringify(sequences));
}
}
function loadModules() {
// This function loads the modules and saved sequences
this.modules = require('./Modules');
if (options.inBrowser)
this.sequences = JSON.parse(window.localStorage.getItem('sequences'));
else
this.sequences = require('./SavedSequences.json');
}
return {
//literals and objects
name: "ImageSequencer",
options: options,
inputlog: inputlog,
modules: modules,
sequences: sequences,
events: events,
steps: steps,
image: image,
//user functions
loadImages: loadImages,
loadImage: loadImages,
addSteps: addSteps,
@@ -167,13 +420,30 @@ ImageSequencer = function ImageSequencer(options) {
insertSteps: insertSteps,
replaceImage: replaceImage,
run: run,
inputlog: inputlog,
modules: modules,
images: images,
ui: options.ui,
setUI: setUI,
exportBin: exportBin,
modulesInfo: modulesInfo,
toCliString: toCliString,
toString: toString,
stepToString: stepToString,
toJSON: toJSON,
stringToJSON: stringToJSON,
stringToJSONstep: stringToJSONstep,
importString: importString,
importJSON: importJSON,
loadNewModule: loadNewModule,
saveNewModule: saveNewModule,
createMetaModule: require('./util/createMetaModule'),
saveSequence: saveSequence,
loadModules: loadModules,
getSteps:getSteps,
//other functions
log: log,
objTypeOf: objTypeOf,
copy: copy
copy: copy,
setInputStep: require('./ui/SetInputStep')(sequencer)
}
}

View File

@@ -1,35 +1,62 @@
function InsertStep(ref, image, index, name, o) {
const getStepUtils = require('./util/getStep.js');
function insertStep(image, index, name, o_) {
ref.log('\x1b[36m%s\x1b[0m','inserting step \"' + name + '\" to \"' + image + '\" at \"'+index+'\".');
// insert one or more steps at a given index in the sequencer
function InsertStep(ref, index, name, o) {
if (ref.sequences[name]) {
return ref.importJSON(ref.sequences[name]);
}
function insertStep(index, name, o_) {
if (ref.modules[name]) var moduleInfo = ref.modules[name][1];
else {
console.log('Module ' + name + ' not found.');
}
var o = ref.copy(o_);
o.id = ref.options.sequencerCounter++; //Gives a Unique ID to each step
o.name = o.name || name;
o.selector = o.selector || 'ismod-' + name;
o.container = o.container || ref.options.selector;
o.image = image;
if(index==-1) index = ref.images[image].steps.length;
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.selector = o_.selector || 'ismod-' + name;
o.container = o_.container || ref.options.selector;
o.inBrowser = ref.options.inBrowser;
var module = ref.modules[name](o);
ref.images[image].steps.splice(index, 0, module);
if (index == -1) index = ref.steps.length;
function defaultSetupModule() {
if (ref.options.ui && ref.options.ui!="none") module.options.ui = ref.options.ui({
selector: o.selector,
title: module.options.title,
id: o.id
});
o.step = {
name: o.name,
description: o.description,
ID: o.number,
inBrowser: ref.options.inBrowser,
ui: ref.options.ui,
options: o
};
var UI = ref.events;
// define the expandSteps function for sequencer
ref.modules[name].expandSteps = function expandSteps(stepsArray) {
for (var i in stepsArray) {
let step = stepsArray[i];
ref.insertSteps(index + Number.parseInt(i), step['name'], step['options']);
}
}
if (module.hasOwnProperty('setup')) module.setup(); // add a default UI, unless the module has one specified
else defaultSetupModule.apply(module); // run default setup() in scope of module (is this right?)
// tell the UI that a step has been inserted.
// Tell UI that a step has been set up.
o = o || {};
if (!ref.modules[name][1].length) {
UI.onSetup(o.step, { index: index });
ref.steps.splice(index, 0, ref.modules[name][0](o, UI));
} else {
ref.modules[name][0](o, UI);
}
return true;
}
insertStep(image, index, name, o);
insertStep(index, name, o);
ref.steps = ref.steps;
}
module.exports = InsertStep;

View File

@@ -1,41 +0,0 @@
function LoadImage(ref, name, src) {
function CImage(src) {
var datauri = (ref.options.inBrowser || src.substring(0,11) == "data:image/")?(src):require('urify')(src);
var image = {
src: datauri,
format: datauri.split(':')[1].split(';')[0].split('/')[1]
}
return image;
}
function loadImage(name, src) {
var image = {
src: src,
steps: [{
options: {
id: ref.options.sequencerCounter++,
name: "load-image",
title: "Load Image"
},
draw: function() {
if(arguments.length==1){
this.output = CImage(arguments[0]);
return true;
}
else if(arguments.length==2) {
this.output = CImage(arguments[0]);
arguments[1]();
return true;
}
return false;
},
output: CImage(src)
}]
};
ref.images[name] = image;
}
return loadImage(name,src);
}
module.exports = LoadImage;

View File

@@ -1,12 +1,44 @@
/*
* Core modules
*/
* Core modules and their info files
*/
module.exports = {
'do-nothing': require('./modules/DoNothing/Module'),
'green-channel': require('./modules/GreenChannel/Module'),
'ndvi-red': require('./modules/NdviRed/Module'),
'do-nothing-pix': require('./modules/DoNothingPix/Module.js'),
'invert': require('./modules/Invert/Module'),
'crop': require('./modules/Crop/Module'),
'segmented-colormap': require('./modules/SegmentedColormap/Module')
'add-qr': require('./modules/AddQR'),
'average': require('./modules/Average'),
'blend': require('./modules/Blend'),
'blur': require('./modules/Blur'),
'brightness': require('./modules/Brightness'),
'canvas-resize': require('./modules/CanvasResize'),
'channel': require('./modules/Channel'),
'colorbar': require('./modules/Colorbar'),
'color-temperature': require('./modules/ColorTemperature'),
'colormap': require('./modules/Colormap'),
'contrast': require('./modules/Contrast'),
'convolution': require('./modules/Convolution'),
'crop': require('./modules/Crop'),
'decode-qr': require('./modules/DecodeQr'),
'dither': require('./modules/Dither'),
'draw-rectangle': require('./modules/DrawRectangle'),
'dynamic': require('./modules/Dynamic'),
'edge-detect': require('./modules/EdgeDetect'),
'exposure': require('./modules/Exposure'),
'flip-image': require('./modules/FlipImage'),
'fisheye-gl': require('./modules/FisheyeGl'),
'histogram': require('./modules/Histogram'),
'gamma-correction': require('./modules/GammaCorrection'),
'gradient': require('./modules/Gradient'),
'grid-overlay': require('./modules/GridOverlay'),
'import-image': require('./modules/ImportImage'),
'invert': require('image-sequencer-invert'),
'ndvi': require('./modules/Ndvi'),
'ndvi-colormap': require('./modules/NdviColormap'),
'paint-bucket': require('./modules/PaintBucket'),
'overlay': require('./modules/Overlay'),
'replace-color': require('./modules/ReplaceColor'),
'resize': require('./modules/Resize'),
'rotate': require('./modules/Rotate'),
'saturation': require('./modules/Saturation'),
'text-overlay': require('./modules/TextOverlay'),
'threshold': require('./modules/Threshold'),
'tint': require('./modules/Tint'),
'white-balance': require('./modules/WhiteBalance')
}

View File

@@ -1,21 +1,37 @@
// Uses a given image as input and replaces it with the output.
// Works only in the browser.
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;
var input = document.querySelectorAll(selector);
if (window.hasOwnProperty('$')) var input = $(selector);
else var input = document.querySelectorAll(selector);
var images = [];
for (var i = 0; i < input.length; i++)
for (var i = 0; i < input.length; i++) {
if (input[i] instanceof HTMLImageElement) images.push(input[i]);
for (var i in images) {
var the_image = images[i];
var url = images[i].src;
var ext = url.split('.').pop();
}
function replaceImage (img, steps) {
var url = img.src;
// refactor to filetypeFromUrl()
var ext = url.split('?')[0].split('.').pop();
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET', url, true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e) {
var arr = new Uint8Array(this.response);
var raw = String.fromCharCode.apply(null,arr);
// in chunks to avoid "RangeError: Maximum call stack exceeded"
// 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);
raw += String.fromCharCode.apply(null, subArray);
}
var base64 = btoa(raw);
var dataURL="data:image/"+ext+";base64," + base64;
make(dataURL);
@@ -25,11 +41,19 @@ function ReplaceImage(ref,selector,steps,options) {
else make(url);
function make(url) {
this_.loadImage('default',url).addSteps('default',steps).run(function(out){
the_image.src = out;
tempSequencer.loadImage(url, function(){
this.addSteps(steps).run({stop:function(){}},function(out){
img.src = out;
});
});
}
}
for (var i = 0; i < images.length; i++) {
replaceImage(images[i],steps);
if (i == images.length-1)
options.callback();
}
}
module.exports = ReplaceImage;

View File

@@ -1,47 +1,89 @@
function Run(ref, json_q, callback) {
function drawStep(drawarray,pos) {
if(pos==drawarray.length) {
var image = drawarray[pos-1].image;
if(ref.objTypeOf(callback)=='Function'){
var steps = ref.images[image].steps;
var out = steps[steps.length-1].output.src;
const getStepUtils = require('./util/getStep.js');
function Run(ref, json_q, callback, ind, progressObj) {
if (!progressObj) progressObj = { stop: function() { } };
function drawStep(drawarray, pos) {
if (pos == drawarray.length && drawarray[pos - 1] !== undefined) {
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);
return true;
}
}
var image = drawarray[pos].image;
var i = drawarray[pos].i;
var input = ref.images[image].steps[i-1].output;
ref.images[image].steps[i].draw(ref.copy(input),function(){
drawStep(drawarray,++pos);
});
// so we don't run on the loadImage module:
if (drawarray[pos] !== undefined) {
var i = drawarray[pos].i;
var input = ref.steps[i - 1].output;
var step = ref.steps[i];
step.getStep = function getStep(offset) {
if (i + offset >= ref.steps.length) return { options: { name: undefined } };
else return ref.steps.slice(i + offset)[0];
};
step.getIndex = function getIndex() {
return i;
}
for (var util in getStepUtils) {
if (getStepUtils.hasOwnProperty(util)) {
step[util] = getStepUtils[util];
}
}
// Tell UI that a step is being drawn.
step.UI.onDraw(step.options.step);
// provides a set of standard tools for each step
var inputForNextStep = require('./RunToolkit')(ref.copy(input));
step.draw(
inputForNextStep,
function onEachStep() {
// This output is accessible by UI
ref.steps[i].options.step.output = ref.steps[i].output.src;
// Tell UI that step has been drawn.
ref.steps[i].UI.onComplete(ref.steps[i].options.step);
drawStep(drawarray, ++pos);
},
progressObj
);
}
}
function drawSteps(json_q) {
var drawarray = [];
for (var image in json_q) {
var no_steps = ref.images[image].steps.length;
var init = json_q[image];
for(var i = 0; i < no_steps-init; i++) {
drawarray.push({image: image,i: init+i});
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 });
}
}
drawStep(drawarray,0);
drawStep(drawarray, ind);
}
function filter(json_q){
for (var image in json_q) {
if (json_q[image]==0 && ref.images[image].steps.length==1)
delete json_q[image];
else if (json_q[image]==0) json_q[image]++;
}
for (var image in json_q) {
var prevstep = ref.images[image].steps[json_q[image]-1];
while (typeof(prevstep) == "undefined" || typeof(prevstep.output) == "undefined") {
prevstep = ref.images[image].steps[(--json_q[image]) - 1];
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];
}
}
return json_q;
}
var json_q = filter(json_q);
return drawSteps(json_q);
}
module.exports = Run;

14
src/RunToolkit.js Normal file
View File

@@ -0,0 +1,14 @@
const getPixels = require('get-pixels');
const pixelManipulation = require('./modules/_nomodule/PixelManipulation');
const lodash = require('lodash');
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;
}

1
src/SavedSequences.json Normal file
View File

@@ -0,0 +1 @@
{"sample":[{"name":"invert","options":{}},{"name":"channel","options":{"channel":"red"}},{"name":"blur","options":{"blur":"5"}}]}

View File

@@ -1,41 +0,0 @@
/*
* Default UI for each image-sequencer module
*/
module.exports = function UserInterface(options) {
options = options || {};
options.container = options.container || ".panels";
options.id = options.id;
options.instanceName = options.instanceName;
options.random = options.random || parseInt(Math.random() * (new Date()).getTime() / 1000000);
options.uniqueSelector = options.uniqueSelector || options.selector + '-' + options.random;
$(options.container).append('<div class="panel ' + options.selector + ' ' + options.uniqueSelector + '" id="sequencer-'+options.id+'"><div class="image"></div></div>');
options.el = options.el || $('.' + options.uniqueSelector);
createLabel(options.el);
// method to remove the UI for a given method, and remove the step
function display(image) {
options.el.find('.image').html(image);
}
// method to remove the UI for a given method, and remove the step
function remove() {
$('div#sequencer-'+options.id).remove();
}
// method to reorder steps, and update the UI
//function move() {}
function createLabel(el) {
if (options.title) el.prepend('<h3 class="title">' + options.title + '</h3> <button class="btn btn-default" onclick="'+options.instanceName+'.removeStep('+options.id+')">Remove Step</button>');
}
return {
el: options.el,
uniqueSelector: options.uniqueSelector,
selector: options.selector,
display: display,
remove: remove
}
}

17
src/cli/installModule.js Normal file
View File

@@ -0,0 +1,17 @@
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!"
);
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!!");
}

7
src/cli/saveSequence.js Normal file
View File

@@ -0,0 +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!!");
}

88
src/cli/sequencerSteps.js Normal file
View File

@@ -0,0 +1,88 @@
var Spinner = require('ora');
var readlineSync = require('readline-sync');
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");
// Iterate through the steps and retrieve their inputs.
program.step.forEach(function(step) {
var options = Object.assign({}, sequencer.modulesInfo(step).inputs);
// If inputs exists, print to console.
if (Object.keys(options).length) {
console.log("[" + step + "]: Inputs");
}
// If inputs exists, print them out with descriptions.
Object.keys(options).forEach(function(input) {
// 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(" ") +
input +
": " +
options[input].desc
);
});
if (program.config) {
try {
var config = JSON.parse(program.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`
);
program.config = false;
console.log(e);
}
}
if (program.config && utils.validateConfig(config, options)) {
console.log("Now using Options object");
Object.keys(options).forEach(function(input) {
options[input] = config[input];
});
} else {
// 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 " +
input +
" (" +
options[input].type +
", default: " +
options[input].default +
"): "
);
options[input] = value;
});
}
// Add the step and its inputs to the sequencer.
sequencer.addSteps(step, options);
});
var spinnerObj = { succeed: () => { }, stop: () => { } };
if (!process.env.TEST)
spinnerObj = Spinner("Your Image is being processed..").start();
// Run the sequencer.
sequencer.run({ progressObj: spinnerObj }, function() {
// Export all images or final image as binary files.
sequencer.exportBin(program.output, program.basic, outputFilename);
//check if spinner was not overriden stop it
if (!spinnerObj.overrideFlag) {
spinnerObj.succeed();
console.log(`\nDone!!`);
}
});
});
}

View File

@@ -0,0 +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');
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
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 };
}
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: UI
}
}

48
src/modules/AddQR/QR.js Normal file
View File

@@ -0,0 +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 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;
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))
}
}
}
callback();
})
})
}

View File

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

View File

@@ -0,0 +1,19 @@
{
"name": "Add QR",
"description": "Adds QR corresponding to the given string",
"url": "https://github.com/publiclab/image-sequencer/tree/master/MODULES.md",
"inputs": {
"size": {
"type": "integer",
"desc": "size of QR code in pixels",
"default": 200
},
"qrCodeString":{
"type": "string",
"desc": "input string to generate QR code",
"default": "https://github.com/publiclab/image-sequencer"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#add-qr-module"
}

74
src/modules/Average/Module.js Executable file
View File

@@ -0,0 +1,74 @@
/*
* Average all pixel colors
*/
module.exports = function Average(options, UI) {
var output;
options.step.metadata = options.step.metadata || {};
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
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++];
}
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);
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;
// 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
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

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

7
src/modules/Average/info.json Executable file
View File

@@ -0,0 +1,7 @@
{
"name": "Average",
"description": "Average all pixel color",
"inputs": {
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#average-module"
}

View File

@@ -0,0 +1,75 @@
module.exports = function Dynamic(options, UI, util) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.func = options.func || defaults.blend;
options.offset = options.offset || defaults.offset;
var output;
// This function is called on every draw.
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
// convert to runnable code:
if (typeof options.func === "string") eval('options.func = ' + options.func);
var getPixels = require('get-pixels');
// 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);
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
});
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

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

17
src/modules/Blend/info.json Executable file
View File

@@ -0,0 +1,17 @@
{
"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": {
"type": "integer",
"desc": "Choose which image to blend the current image with. Two steps back is -2, three steps back is -3 etc.",
"default": -2
},
"blend": {
"type": "string",
"desc": "Function to use to blend the two images.",
"default": "function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] }"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blend-module"
}

84
src/modules/Blur/Blur.js Executable file
View File

@@ -0,0 +1,84 @@
module.exports = exports = function(pixels, blur) {
let kernel = kernelGenerator(blur, 1), oldpix = require('lodash').cloneDeep(pixels);
kernel = flipKernel(kernel);
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;
//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 = [];
for (let i = -2; i <= 2; i++) {
let arr = [];
for (let j = -2; j <= 2; j++)
arr.push([x + i, y + j]);
result.push(arr);
}
return result;
}
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;
}
}

44
src/modules/Blur/Module.js Executable file
View File

@@ -0,0 +1,44 @@
/*
* Blur an Image
*/
module.exports = function Blur(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.blur = options.blur || defaults.blur;
var output;
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
function extraManipulation(pixels) {
pixels = require('./Blur')(pixels, options.blur);
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
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

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

15
src/modules/Blur/info.json Executable file
View File

@@ -0,0 +1,15 @@
{
"name": "Blur",
"description": "Applies a Gaussian blur given by the intensity value",
"inputs": {
"blur": {
"type": "float",
"desc": "Amount of gaussian blur(Less blur gives more detail, typically 0-5)",
"default": 2,
"min": 0,
"max": 5,
"step": 0.25
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blur-module"
}

View File

@@ -0,0 +1,57 @@
/*
* Changes the Image Brightness
*/
module.exports = function Brightness(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback, progressObj) {
options.brightness = options.brightness || defaults.brightness;
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;;
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];
}
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,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

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

View File

@@ -0,0 +1,14 @@
{
"name": "Brightness",
"description": "Change the brightness of the image by given percent value",
"inputs": {
"brightness": {
"type": "integer",
"desc": "% brightness for the new image",
"default": "175",
"min": "0",
"max": "200"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#brightness-module"
}

View File

@@ -0,0 +1,63 @@
/*
* Changes the Canvas Size
*/
module.exports = function canvasResize(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback, progressObj) {
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;
var step = this;
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;
}
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,
inBrowser: options.inBrowser,
callback: callback
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

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

View File

@@ -0,0 +1,26 @@
{
"name": "Resize Canvas",
"description": "This module resizes the canvas and overlays the ouput of the previous step at given location",
"inputs": {
"width": {
"type": "integer",
"desc": "Final width of the canvas",
"default": 1000
},
"height": {
"type": "integer",
"desc": "Final height of the canvas",
"default": 1000
},
"x": {
"type": "integer",
"desc": "X-cord of the top left corner of the image on the canvas",
"default": 500
},
"y": {
"type": "float",
"desc": "Y-cord of the top left corner of the image on the canvas",
"default": 500
}
}
}

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