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>
This commit is contained in:
Varun Gupta
2019-04-07 22:11:14 +05:30
committed by Jeffrey Warren
parent 7cf96df1ee
commit e4e4548c09
8 changed files with 2137 additions and 1803 deletions

3765
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
"main": "src/ImageSequencer.js",
"scripts": {
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
"test": "TEST=true tape test/core/*.js test/core/ui/user-interface.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": "TEST=true 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"
@@ -40,6 +40,7 @@
"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",
@@ -74,4 +75,4 @@
"bin": {
"sequencer": "./index.js"
}
}
}

View File

@@ -9,6 +9,7 @@ module.exports = {
'brightness': require('./modules/Brightness'),
'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'),
@@ -31,12 +32,12 @@ module.exports = {
'ndvi-colormap': require('./modules/NdviColormap'),
'paint-bucket': require('./modules/PaintBucket'),
'overlay': require('./modules/Overlay'),
'replace-color':require('./modules/ReplaceColor'),
'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'),
'color-temperature': require('./modules/ColorTemperature')
'canvas-resize': require('./modules/CanvasResize')
}

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

View File

@@ -69,32 +69,32 @@ module.exports = function PixelManipulation(image, options) {
}
// perform any extra operations on the entire array:
var res;
if (options.extraManipulation) res = options.extraManipulation(pixels,generateOutput);
if (options.extraManipulation) res = options.extraManipulation(pixels, generateOutput);
// there may be a more efficient means to encode an image object,
// but node modules and their documentation are essentially arcane on this point
function generateOutput(){
function generateOutput() {
var chunks = [];
var totalLength = 0;
var r = savePixels(pixels, options.format, { quality: 100 });
var totalLength = 0;
r.on("data", function(chunk) {
totalLength += chunk.length;
chunks.push(chunk);
});
var r = savePixels(pixels, options.format, { quality: 100 });
r.on("end", function() {
var data = Buffer.concat(chunks, totalLength).toString("base64");
var datauri = "data:image/" + options.format + ";base64," + data;
if (options.output)
options.output(options.image, datauri, options.format);
if (options.callback) options.callback();
});
r.on("data", function(chunk) {
totalLength += chunk.length;
chunks.push(chunk);
});
r.on("end", function() {
var data = Buffer.concat(chunks, totalLength).toString("base64");
var datauri = "data:image/" + options.format + ";base64," + data;
if (options.output)
options.output(options.image, datauri, options.format);
if (options.callback) options.callback();
});
}
if(res){
pixels=res;
if (res) {
pixels = res;
generateOutput();
}
else if(!options.extraManipulation) generateOutput();
else if (!options.extraManipulation) generateOutput();
});
};

View File

@@ -0,0 +1,34 @@
var test = require('tape');
require('../../../src/ImageSequencer.js');
var sequencer = ImageSequencer({ ui: false });
var options = { width: 500, height: 500 };
var red = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEX+AAD///+KQee0AAAAAWJLR0QB/wIt3gAAAAd0SU1FB+EGHRIVAvrm6EMAAAAMSURBVAjXY2AgDQAAADAAAceqhY4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDYtMjlUMTg6MjE6MDIrMDI6MDDGD83DAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA2LTI5VDE4OjIxOjAyKzAyOjAwt1J1fwAAAABJRU5ErkJggg==";
// Test 1 to check brightness module is getting loaded
test('Load canvas-resize module', function(t) {
sequencer.loadImages(red);
sequencer.addSteps('canvas-resize', options);
t.equal(sequencer.steps[1].options.name, 'canvas-resize', 'Canvas resize module is getting loaded');
t.end();
});
// Test 2 to check options are correct
test('Check Options', function(t) {
t.equal(sequencer.steps[1].options.width, 500, 'Options are correct');
t.equal(sequencer.steps[1].options.height, 500, 'Options are correct');
t.end();
});
// Test 3 to check brightness module works as expected
test('canvas-resize module works correctly', function(t) {
sequencer.run({ mode: 'test' }, function(out) {
var result = sequencer.steps[1].output.src;
require('get-pixels')(result, (err, pix) => {
t.equal(pix.shape[0], 500);
t.equal(pix.shape[1], 500);
t.end();
});
});
});