mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-11 19:00:00 +01:00
Demo
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -37,3 +37,4 @@ node_modules/*
|
||||
todo.txt
|
||||
test.js
|
||||
output.txt
|
||||
output/
|
||||
|
||||
36015
dist/image-sequencer.js
vendored
36015
dist/image-sequencer.js
vendored
File diff suppressed because one or more lines are too long
1
examples/images/IS-QR.js
Normal file
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
BIN
examples/images/IS-QR.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
examples/images/grid-crop.png
Normal file
BIN
examples/images/grid-crop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
111
examples/index.html
Normal file
111
examples/index.html
Normal file
@@ -0,0 +1,111 @@
|
||||
<!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">
|
||||
|
||||
<title>Image Sequencer</title>
|
||||
|
||||
<link rel="stylesheet" href="demo.css">
|
||||
|
||||
<script src="../dist/image-sequencer.js" charset="utf-8"></script>
|
||||
|
||||
<style media="screen">
|
||||
#addStep select, button, #addStep input {
|
||||
font-family: sans-serif;
|
||||
font-size: 18px !important;
|
||||
height: 30px !important;
|
||||
}
|
||||
.nomargin {
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<header>
|
||||
<h2>Image Sequencer</h2>
|
||||
<h5>Single Image Demo</h5>
|
||||
</header>
|
||||
|
||||
<section id="steps" class="rh">
|
||||
<div class="r">
|
||||
<div class="c">
|
||||
<img src="images/grid.png" alt="">
|
||||
</div>
|
||||
<div class="c rh details">
|
||||
<div class="r"><h4>Original Image</h4></div>
|
||||
<div class="r nomargin">Width: x</div>
|
||||
<div class="r nomargin">Height: y</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="r">
|
||||
<div class="c">
|
||||
<img src="images/grid-crop.png" alt="">
|
||||
</div>
|
||||
<div class="c rh details">
|
||||
<div class="r"><h4>Crop</h4></div>
|
||||
<div class="r nomargin">Width: null (50%)</div>
|
||||
<div class="r nomargin">Height: null (50%)</div>
|
||||
<div class="r nomargin">x: null (0)</div>
|
||||
<div class="r nomargin">y: null (0)</div>
|
||||
<div class="r"><button>Remove</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="addStep">
|
||||
<div class="r">
|
||||
Add Step :
|
||||
<select style="font-family: sans-serif; height: 30px">
|
||||
<option value="" disabled selected>Please Select</option>
|
||||
<option value="crop">Crop</option>
|
||||
<option value="decode-qr">Decode Qr</option>
|
||||
<option value="fisheye-gl">Fisheye GL</option>
|
||||
<option value="green-channel">Green Channel</option>
|
||||
<option value="invert">Invert</option>
|
||||
<option value="ndvi-red">NDVI Red</option>
|
||||
<option value="segmented-colormap">Segmented Colormap</option>
|
||||
</select>
|
||||
<button type="button" name="add">Add Step</button>
|
||||
</div>
|
||||
<div class="r">
|
||||
<div class="c">
|
||||
Options:
|
||||
</div>
|
||||
<div class="c rh">
|
||||
<div class="r">
|
||||
<div class="c">
|
||||
key:
|
||||
</div>
|
||||
<div class="c">
|
||||
<input type="text" name="" value="" placeholder="default"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="r">
|
||||
<div class="c">
|
||||
key:
|
||||
</div>
|
||||
<div class="c">
|
||||
<input type="text" name="" value="" placeholder="default"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
6
index.js
6
index.js
@@ -1,11 +1,13 @@
|
||||
console.log('\x1b[31m%s\x1b[0m',"This is the output of the module");
|
||||
require('./src/ImageSequencer');
|
||||
sequencer = ImageSequencer();
|
||||
sequencer.loadImages({images:{red:'examples/red.jpg'},callback:function(){
|
||||
sequencer.loadImages({images:{red:'examples/images/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.run();
|
||||
sequencer.run(function(){
|
||||
sequencer.exportBin();
|
||||
});
|
||||
}});
|
||||
|
||||
@@ -21,14 +21,17 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": "~3.2.0",
|
||||
"data-uri-to-buffer": "^2.0.0",
|
||||
"fisheyegl": "^0.1.2",
|
||||
"font-awesome": "~4.5.0",
|
||||
"jquery": "~2",
|
||||
"jsqr": "^0.2.2",
|
||||
"urify": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "13.0.0",
|
||||
"buffer": "~5.0.2",
|
||||
"data-uri-to-buffer": "^2.0.0",
|
||||
"get-pixels": "~3.3.0",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-browserify": "^5.0.0",
|
||||
@@ -36,6 +39,7 @@
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"image-filter-core": "~1.0.0",
|
||||
"image-filter-threshold": "~1.0.0",
|
||||
"looks-same": "^3.2.1",
|
||||
"matchdep": "^0.3.0",
|
||||
"plotly.js": "~1.21.2",
|
||||
"save-pixels": "~2.3.4",
|
||||
|
||||
52
src/ExportBin.js
Normal file
52
src/ExportBin.js
Normal file
@@ -0,0 +1,52 @@
|
||||
var getDirectories = function(rootDir, cb) {
|
||||
fs.readdir(rootDir, function(err, files) {
|
||||
var dirs = [];
|
||||
if(typeof(files)=="undefined") {
|
||||
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(ref) {
|
||||
if(ref.options.inBrowser) return false;
|
||||
fs.access('./output/', function(err){
|
||||
if(err) fs.mkdir('output', function() {});
|
||||
});
|
||||
getDirectories('./output',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('output/sequencer'+num,function(){
|
||||
var root = 'output/sequencer'+num+'/';
|
||||
for(var image in ref.images) {
|
||||
var steps = ref.images[image].steps;
|
||||
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(){
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -42,7 +42,8 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
formatInput = require('./FormatInput'),
|
||||
images = {},
|
||||
inputlog = [],
|
||||
events = require('./UserInterface')();
|
||||
events = require('./UserInterface')(),
|
||||
fs = require('fs');
|
||||
|
||||
// if in browser, prompt for an image
|
||||
// if (options.imageSelect || options.inBrowser) addStep('image-select');
|
||||
@@ -175,6 +176,10 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
this.events = require('./UserInterface')(UI);
|
||||
}
|
||||
|
||||
var exportBin = function() {
|
||||
return require('./ExportBin')(this);
|
||||
}
|
||||
|
||||
return {
|
||||
//literals and objects
|
||||
name: "ImageSequencer",
|
||||
@@ -193,6 +198,7 @@ ImageSequencer = function ImageSequencer(options) {
|
||||
replaceImage: replaceImage,
|
||||
run: run,
|
||||
setUI: setUI,
|
||||
exportBin: exportBin,
|
||||
|
||||
//other functions
|
||||
log: log,
|
||||
|
||||
@@ -9,5 +9,6 @@ module.exports = {
|
||||
'invert': require('./modules/Invert/Module'),
|
||||
'crop': require('./modules/Crop/Module'),
|
||||
'segmented-colormap': require('./modules/SegmentedColormap/Module'),
|
||||
'decode-qr': require('./modules/DecodeQr/Module'),
|
||||
'fisheye-gl': require('./modules/FisheyeGl/Module')
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ module.exports = function Crop(input,options,callback) {
|
||||
pixels.shape = [w,h,4];
|
||||
pixels.stride[1] = 4*w;
|
||||
|
||||
options.format = input.format;
|
||||
|
||||
var chunks = [];
|
||||
var totalLength = 0;
|
||||
var r = savePixels(pixels, options.format);
|
||||
|
||||
36
src/modules/DecodeQr/Module.js
Normal file
36
src/modules/DecodeQr/Module.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Decodes QR from a given image.
|
||||
*/
|
||||
module.exports = function DoNothing(options,UI) {
|
||||
options = options || {};
|
||||
options.title = "Decode QR Code";
|
||||
UI.onSetup(options.step);
|
||||
var output;
|
||||
var jsQR = require('jsqr');
|
||||
var getPixels = require('get-pixels');
|
||||
|
||||
function draw(input,callback) {
|
||||
|
||||
UI.onDraw(options.step);
|
||||
|
||||
const step = this;
|
||||
getPixels(input.src,function(err,pixels){
|
||||
if(err) throw err;
|
||||
var w = pixels.shape[0];
|
||||
var h = pixels.shape[1];
|
||||
var decoded = jsQR.decodeQRFromImage(pixels.data,w,h);
|
||||
step.output = input;
|
||||
step.output.data = decoded;
|
||||
callback();
|
||||
options.step.output = input.src;
|
||||
UI.onComplete(options.step);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
options: options,
|
||||
draw: draw,
|
||||
output: output,
|
||||
UI: UI
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var looksSame = require('looks-same');
|
||||
var DataURItoBuffer = require('data-uri-to-buffer');
|
||||
|
||||
// We should only test headless code here.
|
||||
// http://stackoverflow.com/questions/21358015/error-jquery-requires-a-window-with-a-document#25622933
|
||||
@@ -10,8 +12,9 @@ require('../src/ImageSequencer.js');
|
||||
//require image files as DataURLs so they can be tested alike on browser and Node.
|
||||
var sequencer = ImageSequencer({ ui: false });
|
||||
|
||||
var test_png = require('../examples/images/test.png.js');
|
||||
var test_gif = require('../examples/images/test.gif.js');
|
||||
var qr = require('./images/IS-QR.js');
|
||||
var test_png = require('./images/test.png.js');
|
||||
var test_gif = require('./images/test.gif.js');
|
||||
|
||||
sequencer.loadImages(test_png);
|
||||
sequencer.addSteps(['do-nothing-pix','invert','invert']);
|
||||
@@ -23,12 +26,39 @@ test("Preload", function(t) {
|
||||
});
|
||||
|
||||
test("Inverted image isn't identical", function (t) {
|
||||
t.notEqual(sequencer.images.image1.steps[1].output.src, sequencer.images.image1.steps[2].output.src);
|
||||
t.end();
|
||||
var step1 = sequencer.images.image1.steps[1].output.src;
|
||||
var step2 = sequencer.images.image1.steps[2].output.src;
|
||||
step1 = DataURItoBuffer(step1);
|
||||
step2 = DataURItoBuffer(step2);
|
||||
looksSame(step1,step2,function(err,res){
|
||||
if(err) console.log(err);
|
||||
t.equal(res,false);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test("Twice inverted image is identical to original image", function (t) {
|
||||
t.equal(sequencer.images.image1.steps[1].output.src, sequencer.images.image1.steps[3].output.src);
|
||||
var step1 = sequencer.images.image1.steps[1].output.src;
|
||||
var step3 = sequencer.images.image1.steps[3].output.src;
|
||||
step1 = DataURItoBuffer(step1);
|
||||
step3 = DataURItoBuffer(step3);
|
||||
looksSame(step1,step3,function(err,res){
|
||||
if(err) console.log(err);
|
||||
t.equal(res,true);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test("Decode QR module works properly :: setup", function (t) {
|
||||
sequencer.loadImage(qr,function(){
|
||||
this.addSteps('decode-qr').run(function(){
|
||||
t.end();
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
test("Decode QR module works properly :: teardown", function (t) {
|
||||
t.equal("http://github.com/publiclab/image-sequencer",sequencer.images.image2.steps[1].output.data);
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
@@ -42,10 +42,18 @@ test('loadImages loads a DataURL image and creates a step.', function (t){
|
||||
|
||||
if(!sequencer.options.inBrowser)
|
||||
test('loadImage loads an image from URL and creates a step. (NodeJS)', function (t){
|
||||
sequencer.loadImage('URL','https://ccpandhare.github.io/image-sequencer/examples/images/red.jpg', function(){
|
||||
t.equal(sequencer.images.URL.steps.length, 1, "Initial Step Created");
|
||||
t.equal(typeof(sequencer.images.URL.steps[0].output.src), "string", "Initial output exists");
|
||||
t.end();
|
||||
require('dns').resolve('www.github.com', function(err) {
|
||||
if (err) {
|
||||
console.log("Test aborted due to no internet");
|
||||
t.end();
|
||||
}
|
||||
else {
|
||||
sequencer.loadImage('URL','https://ccpandhare.github.io/image-sequencer/examples/images/red.jpg', function(){
|
||||
t.equal(sequencer.images.URL.steps.length, 1, "Initial Step Created");
|
||||
t.equal(typeof(sequencer.images.URL.steps[0].output.src), "string", "Initial output exists");
|
||||
t.end();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
1
test/images/IS-QR.js
Normal file
1
test/images/IS-QR.js
Normal file
File diff suppressed because one or more lines are too long
1
test/images/test.gif.js
Normal file
1
test/images/test.gif.js
Normal file
File diff suppressed because one or more lines are too long
1
test/images/test.png.js
Normal file
1
test/images/test.png.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user