mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-13 20:00:05 +01:00
Compare commits
1 Commits
daemon1024
...
npm-ci
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4e18569cb |
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
${{ runner.os }}-build-
|
${{ runner.os }}-build-
|
||||||
${{ runner.os }}-
|
${{ runner.os }}-
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: npm install
|
run: npm ci
|
||||||
- name: "Base istanbul/tape node tests"
|
- name: "Base istanbul/tape node tests"
|
||||||
run: npm test
|
run: npm test
|
||||||
|
|
||||||
|
|||||||
@@ -78,8 +78,7 @@ body > .container-fluid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hover {
|
.hover {
|
||||||
border: 4px dashed #888888;
|
background: #eee;
|
||||||
background: #F0F0F0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.step {
|
.step {
|
||||||
@@ -334,47 +333,21 @@ a.name-header{
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#update-prompt-modal,.notify-box {
|
#update-prompt-modal {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
margin-left: -125px;
|
margin-left: -125px;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 8px;
|
border-radius: 2px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
left: 10%;
|
left: 10%;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
}
|
}
|
||||||
|
#update-prompt-modal.show {
|
||||||
#update-prompt-modal {
|
|
||||||
width: 30vw;
|
|
||||||
margin: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notify-box {
|
|
||||||
width:34vw;
|
|
||||||
padding:18px;
|
|
||||||
border-radius:8px;
|
|
||||||
margin-left:0.8rem;
|
|
||||||
text-align:left;
|
|
||||||
color:#333;
|
|
||||||
background:#c3c3c3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bootstrap class for display none remove it after updating to version v4 */
|
|
||||||
.d-none {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bootstrap class for display block remove it after updating to version v4 */
|
|
||||||
.d-block {
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#update-prompt-modal.show,.notify-box {
|
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
-webkit-animation: fadein 0.5s;
|
-webkit-animation: fadein 0.5s;
|
||||||
animation: fadein 0.5s;
|
animation: fadein 0.5s;
|
||||||
|
|||||||
@@ -58,15 +58,6 @@
|
|||||||
|
|
||||||
<div id="update-prompt-modal">A new version of image sequencer is available. Click <a href="#" id="reload">here</a> to update.</div>
|
<div id="update-prompt-modal">A new version of image sequencer is available. Click <a href="#" id="reload">here</a> to update.</div>
|
||||||
|
|
||||||
<div class="notify-box d-none">
|
|
||||||
<strong>Failed To Load Image</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" id="close-popup"><span>×</span></button>
|
|
||||||
<div class="notify-msg">
|
|
||||||
Can not Load Image Due to CORS Error Learn more about this
|
|
||||||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors" target="_blank">here</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
<header class="text-center">
|
<header class="text-center">
|
||||||
|
|||||||
@@ -19,42 +19,34 @@ var setupCache = function() {
|
|||||||
// Register the service worker.
|
// Register the service worker.
|
||||||
navigator.serviceWorker.register('sw.js', { scope: '/examples/' })
|
navigator.serviceWorker.register('sw.js', { scope: '/examples/' })
|
||||||
.then(function(registration) {
|
.then(function(registration) {
|
||||||
|
registration.addEventListener('updatefound', () => {
|
||||||
|
// When sw.js has been changed, get a reference to the new service worker.
|
||||||
|
newWorker = registration.installing;
|
||||||
|
newWorker.addEventListener('statechange', () => {
|
||||||
|
// Check if service worker state has changed.
|
||||||
|
switch(newWorker.state) {
|
||||||
|
case 'installed':
|
||||||
|
if(navigator.serviceWorker.controller) {
|
||||||
|
// New service worker available; prompt the user to update.
|
||||||
|
showUpdateModal();
|
||||||
|
}
|
||||||
|
// No updates available; do nothing.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return new Promise(function(resolve,reject){
|
const installingWorker = registration.installing;
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
registration.addEventListener('updatefound', () => {
|
console.log(installingWorker);
|
||||||
// When sw.js has been changed, get a reference to the new service worker.
|
if (installingWorker.state === 'installed') {
|
||||||
newWorker = registration.installing;
|
location.reload();
|
||||||
|
}
|
||||||
if(!newWorker){
|
};
|
||||||
return reject(new Error('error in installing service worker'));
|
console.log('Registration successful, scope is:', registration.scope);
|
||||||
}
|
})
|
||||||
|
.catch(function(error) {
|
||||||
newWorker.addEventListener('statechange', () => {
|
console.log('Service worker registration failed, error:', error);
|
||||||
// Check if service worker state has changed.
|
|
||||||
switch(newWorker.state) {
|
|
||||||
case 'installed':
|
|
||||||
if(navigator.serviceWorker.controller) {
|
|
||||||
// New service worker available; prompt the user to update.
|
|
||||||
showUpdateModal();
|
|
||||||
$('#reload').on('click',(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
console.log('New Service Worker Installed Successfully');
|
|
||||||
location.reload();
|
|
||||||
return resolve();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// No updates available; do nothing.
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'redundant':
|
|
||||||
return reject(new Error('installing new service worker now became redundant'));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
console.log('Failed In Registering Service Worker: ',err);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,22 +69,21 @@ var setupCache = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearCache = () => {
|
$('#clear-cache').click(function() {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
return caches.keys()
|
caches.keys().then(function(cacheNames) {
|
||||||
.then(function(cache) {
|
cacheNames.forEach(function(cacheName) {
|
||||||
return Promise.all(cache.map(function(cacheItem) {
|
caches.delete(cacheName);
|
||||||
return caches.delete(cacheItem);
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$('#clear-cache').click(function() {
|
|
||||||
clearCache();
|
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = setupCache;
|
module.exports = setupCache;
|
||||||
|
|||||||
@@ -47,12 +47,7 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addStepUi() {
|
function addStepUi() {
|
||||||
|
if ($(addStepSel + ' select').val() == 'none') return;
|
||||||
if ($(addStepSel + ' select').val() == ''){
|
|
||||||
alert('Please Select a Step to Proceed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newStepName;
|
var newStepName;
|
||||||
if(typeof arguments[0] !== 'string')
|
if(typeof arguments[0] !== 'string')
|
||||||
newStepName = $(addStepSel + ' select option').html().toLowerCase().split(' ').join('-');
|
newStepName = $(addStepSel + ' select option').html().toLowerCase().split(' ').join('-');
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
if (step.options && step.options.description)
|
if (step.options && step.options.description)
|
||||||
step.description = step.options.description;
|
step.description = step.options.description;
|
||||||
|
|
||||||
let stepDocsLink = '';
|
|
||||||
if (step.moduleInfo) stepDocsLink = step.moduleInfo['docs-link'] || '';
|
|
||||||
|
|
||||||
step.ui = // Basic UI markup for the step
|
step.ui = // Basic UI markup for the step
|
||||||
'\
|
'\
|
||||||
<div class="container-fluid step-container">\
|
<div class="container-fluid step-container">\
|
||||||
@@ -51,7 +48,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
<div class="row step">\
|
<div class="row step">\
|
||||||
<div class="col-md-4 details container-fluid">\
|
<div class="col-md-4 details container-fluid">\
|
||||||
<div class="cal collapse in"><p>' +
|
<div class="cal collapse in"><p>' +
|
||||||
'<a href="' + stepDocsLink + '">' + (step.description || '') + '</a>' +
|
'<a href="https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#' + step.name + '-module">' + (step.description || '') + '</a>' +
|
||||||
'</p></div>\
|
'</p></div>\
|
||||||
</div>\
|
</div>\
|
||||||
<div class="col-md-8 cal collapse in step-column">\
|
<div class="col-md-8 cal collapse in step-column">\
|
||||||
@@ -121,14 +118,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
paramVal + '">' + '<span class="input-group-addon"><i></i></span>' +
|
paramVal + '">' + '<span class="input-group-addon"><i></i></span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
else if(inputDesc.type === 'button'){
|
else { // Non color-picker input types
|
||||||
html = '<div><button name="' + paramName + '" type="' + inputDesc.type + '" >\
|
|
||||||
<i class="fa fa-crosshairs"></i></button>\
|
|
||||||
<span>click to select coordinates</span>\
|
|
||||||
</div>';
|
|
||||||
}
|
|
||||||
else { // Non color-picker input types and other than a button
|
|
||||||
|
|
||||||
html =
|
html =
|
||||||
'<input class="form-control target" type="' +
|
'<input class="form-control target" type="' +
|
||||||
inputDesc.type +
|
inputDesc.type +
|
||||||
@@ -339,23 +329,11 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
|
|
||||||
$stepAll('.download-btn').on('click', () => {
|
$stepAll('.download-btn').on('click', () => {
|
||||||
|
|
||||||
function dataURLtoBlob(dataurl) {
|
|
||||||
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
|
||||||
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
|
||||||
while(n--){
|
|
||||||
u8arr[n] = bstr.charCodeAt(n);
|
|
||||||
}
|
|
||||||
return new Blob([u8arr], {type:mime});
|
|
||||||
}
|
|
||||||
|
|
||||||
var element = document.createElement('a');
|
var element = document.createElement('a');
|
||||||
|
element.setAttribute('href', step.output);
|
||||||
element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src));
|
element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src));
|
||||||
element.style.display = 'none';
|
element.style.display = 'none';
|
||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
var blob = dataURLtoBlob(step.output);
|
|
||||||
var objurl = URL.createObjectURL(blob);
|
|
||||||
element.setAttribute('href', objurl);
|
|
||||||
|
|
||||||
element.click();
|
element.click();
|
||||||
});
|
});
|
||||||
@@ -421,19 +399,6 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
|
|
||||||
var img = $(step.imgElement);
|
var img = $(step.imgElement);
|
||||||
|
|
||||||
let customXCoord = '20'; //default x coordinate
|
|
||||||
let customYCoord = '20'; //default y coordinate
|
|
||||||
|
|
||||||
const customButton = $('button[name="Custom-Coordinates"]');
|
|
||||||
img.click(function(e) {
|
|
||||||
customXCoord = e.offsetX;
|
|
||||||
customYCoord = e.offsetY;
|
|
||||||
customButton.click(function() {
|
|
||||||
$('input[name="x"]').val(customXCoord);
|
|
||||||
$('input[name="y"]').val(customYCoord);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
img.mousemove(function(e) {
|
img.mousemove(function(e) {
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
canvas.width = img.width();
|
canvas.width = img.width();
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ function mapHtmlTypes(inputInfo){
|
|||||||
htmlType = inputInfo.min != undefined ? 'range' : 'text';
|
htmlType = inputInfo.min != undefined ? 'range' : 'text';
|
||||||
if (htmlType === 'range') inputInfo.step = inputInfo.step || 0.1; // default range step size for float
|
if (htmlType === 'range') inputInfo.step = inputInfo.step || 0.1; // default range step size for float
|
||||||
break;
|
break;
|
||||||
case 'coordinate-input':
|
|
||||||
htmlType = 'button';
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
htmlType = 'text';
|
htmlType = 'text';
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Error 502 | Bad Gateway</title>
|
|
||||||
<style>
|
|
||||||
body{
|
|
||||||
background-color:#d3d3d3;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
font-size:20px;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
display: flex;
|
|
||||||
flex-direction:column;
|
|
||||||
text-align: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color:blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<main>
|
|
||||||
<p>Error 502: something went wrong.</p>
|
|
||||||
<p>It seems that you are not connected to internet.<br>Please try after some time.</p>
|
|
||||||
<a href="/">Go To Home Page</a>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,14 +1,6 @@
|
|||||||
const staticCacheName = 'image-sequencer-static-v3.6.0';
|
const staticCacheName = 'image-sequencer-static-v3.6.0';
|
||||||
self.addEventListener('install', function(e) {
|
self.addEventListener('install', event => {
|
||||||
e.waitUntil(
|
console.log('Attempting to install service worker');
|
||||||
caches.open(staticCacheName).then(function(cache) {
|
|
||||||
console.log('Attempting to install service worker');
|
|
||||||
return cache.addAll([
|
|
||||||
'/',
|
|
||||||
'/examples/offline.html'
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener('activate', function(e) {
|
self.addEventListener('activate', function(e) {
|
||||||
@@ -29,28 +21,16 @@ self.addEventListener('activate', function(e) {
|
|||||||
|
|
||||||
self.addEventListener('fetch', function(event) {
|
self.addEventListener('fetch', function(event) {
|
||||||
event.respondWith(
|
event.respondWith(
|
||||||
// Try to fetch the latest data first.
|
caches.open(staticCacheName).then(function(cache) {
|
||||||
fetch(event.request)
|
return cache.match(event.request).then(function (response) {
|
||||||
.then(function(response) {
|
return response || fetch(event.request).then(function(response) {
|
||||||
return caches.open(staticCacheName)
|
if(event.request.method == 'GET')
|
||||||
.then(function(cache) {
|
cache.put(event.request, response.clone());
|
||||||
if(event.request.method == 'GET'){
|
return response;
|
||||||
cache.put(event.request.url, response.clone());
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(function(err) {
|
|
||||||
// Now the request has been failed so show cached data.
|
|
||||||
return caches.match(event.request).then(function(res){
|
|
||||||
if (res === undefined) {
|
|
||||||
// Display offline page
|
|
||||||
return caches.match('offline.html');
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// When the update modal sends a 'skipWaiting' message, call the skipWaiting method.
|
// When the update modal sends a 'skipWaiting' message, call the skipWaiting method.
|
||||||
|
|||||||
88
index.js
88
index.js
@@ -1,5 +1,89 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
var cli = require('./src/cli');
|
require('./src/ImageSequencer');
|
||||||
|
sequencer = ImageSequencer({ ui: true });
|
||||||
|
var fs = require('fs');
|
||||||
|
var program = require('commander');
|
||||||
|
var utils = require('./src/CliUtils');
|
||||||
|
|
||||||
cli(process.argv);
|
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.');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
1646
package-lock.json
generated
1646
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -41,12 +41,11 @@
|
|||||||
"bootstrap": "^3.4.1",
|
"bootstrap": "^3.4.1",
|
||||||
"bootstrap-colorpicker": "^2.5.3",
|
"bootstrap-colorpicker": "^2.5.3",
|
||||||
"buffer": "~6.0.2",
|
"buffer": "~6.0.2",
|
||||||
"commander": "^7.0.0",
|
"commander": "^6.2.0",
|
||||||
"compressorjs": "^1.0.5",
|
"compressorjs": "^1.0.5",
|
||||||
"data-uri-to-buffer": "^3.0.0",
|
"data-uri-to-buffer": "^3.0.0",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
"eslint": "^6.1.0",
|
"eslint": "^6.1.0",
|
||||||
"expr-eval": "^2.0.2",
|
|
||||||
"fisheyegl": "^0.1.2",
|
"fisheyegl": "^0.1.2",
|
||||||
"font-awesome": "~4.7.0",
|
"font-awesome": "~4.7.0",
|
||||||
"geotiff": "^1.0.0-beta.6",
|
"geotiff": "^1.0.0-beta.6",
|
||||||
@@ -109,7 +108,7 @@
|
|||||||
"matchdep": "^2.0.0",
|
"matchdep": "^2.0.0",
|
||||||
"resemblejs": "^3.2.5",
|
"resemblejs": "^3.2.5",
|
||||||
"tap-spec": "^5.0.0",
|
"tap-spec": "^5.0.0",
|
||||||
"tape": "^5.2.0",
|
"tape": "^4.9.2",
|
||||||
"tape-run": "^8.0.0",
|
"tape-run": "^8.0.0",
|
||||||
"uglify-es": "^3.3.7"
|
"uglify-es": "^3.3.7"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ module.exports = {
|
|||||||
'import-image': require('./modules/ImportImage'),
|
'import-image': require('./modules/ImportImage'),
|
||||||
'mask': require('./modules/Mask'),
|
'mask': require('./modules/Mask'),
|
||||||
'minify-image': require('./modules/MinifyImage'),
|
'minify-image': require('./modules/MinifyImage'),
|
||||||
// 'invert': require('image-sequencer-invert'), this code imports the invert module from a different repository altogether (using a require statement)
|
// 'invert': require('image-sequencer-invert'),
|
||||||
// Which is a powerful feature of ImageSequencer, the modules are independent of the rest of the library's source.
|
|
||||||
'invert': require('./modules/Invert'),
|
'invert': require('./modules/Invert'),
|
||||||
'ndvi': require('./modules/Ndvi'),
|
'ndvi': require('./modules/Ndvi'),
|
||||||
'ndvi-colormap': require('./modules/NdviColormap'),
|
'ndvi-colormap': require('./modules/NdviColormap'),
|
||||||
|
|||||||
102
src/cli/index.js
102
src/cli/index.js
@@ -1,102 +0,0 @@
|
|||||||
require('../ImageSequencer');
|
|
||||||
sequencer = ImageSequencer({ ui: true });
|
|
||||||
var fs = require('fs');
|
|
||||||
var { Command } = require('commander');
|
|
||||||
var utils = require('../CliUtils');
|
|
||||||
|
|
||||||
var saveSequence = require('./saveSequence.js');
|
|
||||||
var installModule = require('./installModule.js');
|
|
||||||
var sequencerSteps = require('./sequencerSteps.js');
|
|
||||||
|
|
||||||
function exit(message) {
|
|
||||||
console.error(message);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function executeSteps(program) {
|
|
||||||
// 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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseSteps(program) {
|
|
||||||
// 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.');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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/';
|
|
||||||
|
|
||||||
executeSteps(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
function cli(args) {
|
|
||||||
|
|
||||||
let program = new Command();
|
|
||||||
|
|
||||||
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(args);
|
|
||||||
|
|
||||||
const options = program.opts();
|
|
||||||
if (options.saveSequence) saveSequence(options, sequencer);
|
|
||||||
else if (options.installModule) installModule(options, sequencer);
|
|
||||||
else parseSteps(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = cli;
|
|
||||||
@@ -14,10 +14,11 @@ module.exports = function Dynamic(options, UI) {
|
|||||||
options.blue = options.blue || defaults.blue;
|
options.blue = options.blue || defaults.blue;
|
||||||
options.green = options.green || defaults.green;
|
options.green = options.green || defaults.green;
|
||||||
|
|
||||||
const Parser = require('expr-eval').Parser;
|
|
||||||
function generator(expression) {
|
function generator(expression) {
|
||||||
let expr = Parser.parse('R = r; G = g; B = b; A = a; ' + expression);
|
var func = 'f = function (r, g, b, a) { var R = r, G = g, B = b, A = a; return ' + expression + ';}';
|
||||||
return expr.toJSFunction("r,g,b,a,R,G,B,A");
|
var f;
|
||||||
|
eval(func);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
var channels = ['red', 'green', 'blue', 'alpha'];
|
var channels = ['red', 'green', 'blue', 'alpha'];
|
||||||
@@ -25,7 +26,8 @@ module.exports = function Dynamic(options, UI) {
|
|||||||
channels.forEach(function(channel) {
|
channels.forEach(function(channel) {
|
||||||
if (channel === 'alpha'){
|
if (channel === 'alpha'){
|
||||||
options['alpha_function'] = function() { return 255; };
|
options['alpha_function'] = function() { return 255; };
|
||||||
} else {
|
}
|
||||||
|
else{
|
||||||
options[channel + '_function'] = generator(options[channel]);
|
options[channel + '_function'] = generator(options[channel]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,10 +8,6 @@
|
|||||||
"desc": "Enter the text to overlay.",
|
"desc": "Enter the text to overlay.",
|
||||||
"default": "Lorem ipsum"
|
"default": "Lorem ipsum"
|
||||||
},
|
},
|
||||||
"Custom-Coordinates": {
|
|
||||||
"type": "coordinate-input",
|
|
||||||
"desc": "Click to fill Coordinates"
|
|
||||||
},
|
|
||||||
"x": {
|
"x": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"desc": "Starting text horizontal position.",
|
"desc": "Starting text horizontal position.",
|
||||||
|
|||||||
@@ -7,22 +7,6 @@ function LoadImage(ref, name, src, main_callback) {
|
|||||||
};
|
};
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to check whether a image can be fetched from external source or not
|
|
||||||
function checkForError(image_url) {
|
|
||||||
return fetch(image_url).then(function(res) {
|
|
||||||
if(res)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}).catch(function(err) {
|
|
||||||
if(err)
|
|
||||||
console.log('Error occured because of image URL ',err);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function CImage(src, step, callback) {
|
function CImage(src, step, callback) {
|
||||||
var datauri;
|
var datauri;
|
||||||
if (src.match(/^data:/i)) {
|
if (src.match(/^data:/i)) {
|
||||||
@@ -41,42 +25,18 @@ function LoadImage(ref, name, src, main_callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (ref.options.inBrowser) {
|
else if (ref.options.inBrowser) {
|
||||||
|
var ext = src.split('.').pop();
|
||||||
let notifyBox = document.querySelector('div.notify-box');
|
var image = document.createElement('img');
|
||||||
let closePopUP = document.getElementById('close-popup');
|
var canvas = document.createElement('canvas');
|
||||||
if(src.indexOf('images/') !== 0 && src.indexOf('./images/') !== 0 && checkForError(src)){
|
var context = canvas.getContext('2d');
|
||||||
|
image.onload = function() {
|
||||||
if(notifyBox){
|
canvas.width = image.naturalWidth;
|
||||||
notifyBox.classList.remove('d-none');
|
canvas.height = image.naturalHeight;
|
||||||
notifyBox.classList.add('d-block');
|
context.drawImage(image, 0, 0);
|
||||||
}
|
datauri = canvas.toDataURL(ext);
|
||||||
|
callback(datauri, step);
|
||||||
if(closePopUP){
|
};
|
||||||
closePopUP.addEventListener('click',function(){
|
image.src = src;
|
||||||
if(notifyBox){
|
|
||||||
notifyBox.classList.remove('d-block');
|
|
||||||
notifyBox.classList.add('d-none');
|
|
||||||
}
|
|
||||||
if(document.querySelector('button.remove'))
|
|
||||||
document.querySelector('button.remove').click(); // Remove the step due to redundant processing.
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
var ext = src.split('.').pop();
|
|
||||||
var image = document.createElement('img');
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
var context = canvas.getContext('2d');
|
|
||||||
image.onload = function() {
|
|
||||||
canvas.width = image.naturalWidth;
|
|
||||||
canvas.height = image.naturalHeight;
|
|
||||||
context.drawImage(image, 0, 0);
|
|
||||||
datauri = canvas.toDataURL(ext);
|
|
||||||
callback(datauri, step);
|
|
||||||
};
|
|
||||||
image.src = src;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
datauri = require('urify')(src);
|
datauri = require('urify')(src);
|
||||||
|
|||||||
@@ -52,10 +52,9 @@ function setInputStepInit() {
|
|||||||
video.play();
|
video.play();
|
||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById('capture').addEventListener('click', function(){
|
document.getElementById('capture').addEventListener('click', function(stream){
|
||||||
context.drawImage(video, 0, 0, 400, 300);
|
context.drawImage(video, 0, 0, 400, 300);
|
||||||
options.onTakePhoto(canvas.toDataURL());
|
options.onTakePhoto(canvas.toDataURL());
|
||||||
setTimeout(stopStream(stream),1); // wait for 1 second before closing webcam so that image loads properly
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('close').addEventListener('click', function () {
|
document.getElementById('close').addEventListener('click', function () {
|
||||||
@@ -114,10 +113,10 @@ function setInputStepInit() {
|
|||||||
dropzone[0].addEventListener('drop', handleFile, false);
|
dropzone[0].addEventListener('drop', handleFile, false);
|
||||||
|
|
||||||
dropzone.on('dragover', function onDragover(e) {
|
dropzone.on('dragover', function onDragover(e) {
|
||||||
dropzone.addClass('hover');
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
});
|
e.preventDefault();
|
||||||
|
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
||||||
|
}, false);
|
||||||
|
|
||||||
dropzone.on('dragenter', function onDragEnter(e) {
|
dropzone.on('dragenter', function onDragEnter(e) {
|
||||||
dropzone.addClass('hover');
|
dropzone.addClass('hover');
|
||||||
@@ -127,11 +126,6 @@ function setInputStepInit() {
|
|||||||
dropzone.removeClass('hover');
|
dropzone.removeClass('hover');
|
||||||
});
|
});
|
||||||
|
|
||||||
dropzone.on('drop', function onDrop(e) {
|
|
||||||
dropzone.removeClass('hover');
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/** Parses the defaults and gets the input which is available. */
|
|
||||||
module.exports = function(info){
|
module.exports = function(info){
|
||||||
var defaults = {};
|
var defaults = {};
|
||||||
for (var key in info.inputs) {
|
for (var key in info.inputs) {
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
/**
|
|
||||||
* @param {number} x x-coordinate.
|
|
||||||
* @param {number} y y-coordinate.
|
|
||||||
* @param {object} value array [r, g, b, a]
|
|
||||||
* @param {object} pixels NDarray of pixels.
|
|
||||||
* @description Sets the pixels from 0 through length of value.
|
|
||||||
*/
|
|
||||||
module.exports = function(x, y, value, pixels){
|
module.exports = function(x, y, value, pixels){
|
||||||
for(let i = 0; i < value.length; i++){
|
for(let i = 0; i < value.length; i++){
|
||||||
pixels.set(x, y, i, value[i]);
|
pixels.set(x, y, i, value[i]);
|
||||||
|
|||||||
@@ -1,20 +1,36 @@
|
|||||||
|
require('../../src/ImageSequencer');
|
||||||
|
sequencer = ImageSequencer({ ui: true });
|
||||||
|
const saveSequence = require('../../src/cli/saveSequence.js');
|
||||||
const test = require('tape');
|
const test = require('tape');
|
||||||
const cli = require('../../src/cli');
|
const { Command } = require('commander');
|
||||||
|
|
||||||
|
|
||||||
test('testing save sequence function', function (t) {
|
test('testing save sequence function', function (t) {
|
||||||
try {
|
try {
|
||||||
cli([
|
let program = new Command();
|
||||||
'node', 'test',
|
program
|
||||||
'--save-sequence',
|
.option('--save-sequence [string]', 'Name space separated with Stringified sequence');
|
||||||
'"invert-colormap invert(),colormap()"',
|
|
||||||
]);
|
program.parse(['node', 'test', '--save-sequence', '"invert brightness"']);
|
||||||
|
|
||||||
|
if (program.saveSequence)
|
||||||
|
saveSequence(program, sequencer);
|
||||||
t.true(1, 'creation success');
|
t.true(1, 'creation success');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
t.true(!error, 'creation fail');
|
t.true(!error, 'creation fail');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
cli(['node', 'test', '--save-sequence']);
|
let program = new Command();
|
||||||
|
program
|
||||||
|
.option('--save-sequence [string]', 'Name space separated with Stringified sequence');
|
||||||
|
|
||||||
|
program.parse(['node', 'test', '--save-sequence']);
|
||||||
|
|
||||||
|
if (program.saveSequence)
|
||||||
|
saveSequence(program, sequencer);
|
||||||
t.true(0, 'creation success');
|
t.true(0, 'creation success');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
t.true(1, 'creation fail');
|
t.true(1, 'creation fail');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
const test = require('tape');
|
|
||||||
const cli = require('../../src/cli');
|
|
||||||
const stdout = require('./util/readConsole').stdout;
|
|
||||||
const stderr = require('./util/readConsole').stderr;
|
|
||||||
|
|
||||||
function sleep(ms) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
test('testing steps parsing', function (t) {
|
|
||||||
|
|
||||||
t.plan(1);
|
|
||||||
|
|
||||||
let out = stdout.read();
|
|
||||||
|
|
||||||
cli([
|
|
||||||
'node', 'test',
|
|
||||||
'-i', 'examples/images/test.png',
|
|
||||||
'-s', 'invert',
|
|
||||||
]);
|
|
||||||
|
|
||||||
sleep(1000).then(() => {
|
|
||||||
out.restore();
|
|
||||||
let validator = out.output().includes('Added Step "invert"');
|
|
||||||
t.true(validator, 'Steps parsed successfully');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// let err = stderr.read();
|
|
||||||
// await cli([
|
|
||||||
// 'node', 'test',
|
|
||||||
// '-i', 'examples/images/test.png',
|
|
||||||
// '-s', 'invalidStep',
|
|
||||||
// ]);
|
|
||||||
// err.restore();
|
|
||||||
// t.equal(err.output, 'Please ensure all steps are valid.');
|
|
||||||
});
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
function ReadLog(stream) {
|
|
||||||
this._stream = stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadLog.prototype.read = function(options) {
|
|
||||||
|
|
||||||
let output = '';
|
|
||||||
let stream = this._stream;
|
|
||||||
|
|
||||||
let originalStreamWrite = stream.write;
|
|
||||||
stream.write = function(string) {
|
|
||||||
output += string;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
output: function () {
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
restore: function() {
|
|
||||||
stream.write = originalStreamWrite;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.stdout = new ReadLog(process.stdout);
|
|
||||||
exports.stderr = new ReadLog(process.stderr);
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
var setUpCache = new require('../../../examples/lib/cache')();
|
|
||||||
var test = require('tape');
|
|
||||||
|
|
||||||
function SWInstallation(){
|
|
||||||
return new Promise(() => {
|
|
||||||
return setupCache();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function UnRegisterSW(){
|
|
||||||
|
|
||||||
function unregister() {
|
|
||||||
return navigator.serviceWorker.getRegistrations()
|
|
||||||
.then(function(registrations) {
|
|
||||||
var unRegisteredWorker = registrations.map(function(registration) {
|
|
||||||
return registration.unregister();
|
|
||||||
});
|
|
||||||
return Promise.all(unRegisteredWorker);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all([
|
|
||||||
unregister(),
|
|
||||||
setUpCache.clearCache()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
test('Register service worker',function(t) {
|
|
||||||
|
|
||||||
t.test('unregister service worker',function(st) {
|
|
||||||
st.equal(UnRegisterSW(),true,'unregistered successfully and cleared the cache')
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('install service worker',function(st) {
|
|
||||||
st.equal(SWInstallation(),true,'successfully installed new service worker')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -24,9 +24,6 @@ module.exports = (moduleName, options, benchmark, input) => {
|
|||||||
sequencer.loadImages(input || red);
|
sequencer.loadImages(input || red);
|
||||||
// Add the step.
|
// Add the step.
|
||||||
sequencer.addSteps(moduleName, options[0]);
|
sequencer.addSteps(moduleName, options[0]);
|
||||||
|
|
||||||
t.plan(2);
|
|
||||||
|
|
||||||
// Run the ImageSequencer with initial option.
|
// Run the ImageSequencer with initial option.
|
||||||
sequencer.run(() => {
|
sequencer.run(() => {
|
||||||
let result = sequencer.steps[1].output.src;
|
let result = sequencer.steps[1].output.src;
|
||||||
@@ -40,7 +37,7 @@ module.exports = (moduleName, options, benchmark, input) => {
|
|||||||
looksSame(result, benchmark[0], function(err, res) {
|
looksSame(result, benchmark[0], function(err, res) {
|
||||||
if (err) console.log(err);
|
if (err) console.log(err);
|
||||||
|
|
||||||
t.equal(res.equal, true, `${moduleName} module works correctly with initial option ${JSON.stringify(options[0])}`);
|
t.equal(res.equal, true, `${moduleName} module works correctly with initial option ${options[0][moduleName]}`);
|
||||||
});
|
});
|
||||||
// Change the option of the given module.
|
// Change the option of the given module.
|
||||||
sequencer.steps[1].setOptions(options[1]);
|
sequencer.steps[1].setOptions(options[1]);
|
||||||
@@ -57,8 +54,9 @@ module.exports = (moduleName, options, benchmark, input) => {
|
|||||||
looksSame(newResult, benchmark[1], function(err, res) {
|
looksSame(newResult, benchmark[1], function(err, res) {
|
||||||
if (err) console.log(err);
|
if (err) console.log(err);
|
||||||
|
|
||||||
t.equal(res.equal, true, `${moduleName} module works correctly when the option is changed to ${JSON.stringify(options[1])}`);
|
t.equal(res.equal, true, `${moduleName} module works correctly when the option is changed to ${options[1][moduleName]}`);
|
||||||
sequencer = null;
|
sequencer = null;
|
||||||
|
t.end();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ test('convolve works with 1x1 array', t => {
|
|||||||
[1, 1, 1]
|
[1, 1, 1]
|
||||||
],
|
],
|
||||||
expectedOut = [
|
expectedOut = [
|
||||||
new Float32Array([9])
|
[9]
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = convolve([array], kernel);
|
const out = convolve([array], kernel);
|
||||||
@@ -34,10 +34,10 @@ test('convolve works with 3x4 array', t => {
|
|||||||
[1, 1, 1]
|
[1, 1, 1]
|
||||||
],
|
],
|
||||||
expectedOut = [
|
expectedOut = [
|
||||||
new Float32Array([12, 19, 26]),
|
[12, 19, 26],
|
||||||
new Float32Array([13, 20, 27]),
|
[13, 20, 27],
|
||||||
new Float32Array([13, 20, 27]),
|
[13, 20, 27],
|
||||||
new Float32Array([13, 19, 25])
|
[13, 19, 25]
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = convolve([array], kernel);
|
const out = convolve([array], kernel);
|
||||||
@@ -68,16 +68,16 @@ test('convolve works with multiple 3x4 arrays', t => {
|
|||||||
[1, 1, 1]
|
[1, 1, 1]
|
||||||
],
|
],
|
||||||
expectedOut1 = [
|
expectedOut1 = [
|
||||||
new Float32Array([12, 19, 26]),
|
[12, 19, 26],
|
||||||
new Float32Array([13, 20, 27]),
|
[13, 20, 27],
|
||||||
new Float32Array([13, 20, 27]),
|
[13, 20, 27],
|
||||||
new Float32Array([13, 19, 25])
|
[13, 19, 25]
|
||||||
],
|
],
|
||||||
expectedOut2 = [
|
expectedOut2 = [
|
||||||
new Float32Array([14, 19, 24]),
|
[14, 19, 24],
|
||||||
new Float32Array([12, 13, 14]),
|
[12, 13, 14],
|
||||||
new Float32Array([15, 12, 9]),
|
[15, 12, 9],
|
||||||
new Float32Array([16, 13, 10])
|
[16, 13, 10]
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = convolve([array1, array2], kernel);
|
const out = convolve([array1, array2], kernel);
|
||||||
|
|||||||
Reference in New Issue
Block a user