Skip to content

Commit

Permalink
Merge pull request #1 from jonathanlurie/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
jonathanlurie authored Mar 9, 2017
2 parents 396d43d + ae58c63 commit 47101cc
Show file tree
Hide file tree
Showing 18 changed files with 1,091 additions and 275 deletions.
343 changes: 275 additions & 68 deletions dist/pixpipe.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/pixpipe.js.map

Large diffs are not rendered by default.

523 changes: 417 additions & 106 deletions doc/index.html

Large diffs are not rendered by default.

24 changes: 7 additions & 17 deletions examples/fileToImage2D.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,30 @@

var fileInput = document.getElementById('fileInput');


// create a filter to write the image into a canvas
var imageToCanvasFilter = new pixpipe.CanvasImageWriter( "myDiv" );
var imageToCanvasFilter = new pixpipe.CanvasImageWriter();
imageToCanvasFilter.setMetadata( "parentDivID", "myDiv" );

// The filter to read image from URL
var file2ImgFilter = new pixpipe.FileImageReader(

// the image is loaded...
// here, filter = url2ImgFilter
function(filter){
var file2ImgFilter = new pixpipe.FileImageReader();

// the image is loaded...
// here, filter = url2ImgFilter
file2ImgFilter.on("imageLoaded", function( filter ){
// use the output of the UrlImageReader as the input for CanvasImageWriter
imageToCanvasFilter.addInput( filter.getOutput() );

// actually copy the data from the Image2D into the inner HTML5 canvas
imageToCanvasFilter.update();

}
);

});

fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];

// set the input, an HTML5 File object
file2ImgFilter.addInput(file)

// Ask to fetch the image from URL
file2ImgFilter.update();
});




}
</script>

Expand Down
79 changes: 79 additions & 0 deletions examples/forEachPixel.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<html>
<head>
<title>URL to Image2D</title>

<script src="../dist/pixpipe.js"></script>

<style>
canvas,
.smaller{
width: 50vw;
height: auto;
}
</style>
</head>
<body>
<p>
<p>The original image</p>
<img class="smaller" src="images/sd.jpg"></img>
</p>

<p>
<p>The transformed image, with switched chanels</p>
<div class="smaller" id="myDiv"></div>
</p>

<script>

// create a filter to write the image into a canvas
var imageToCanvasFilter = new pixpipe.CanvasImageWriter();
imageToCanvasFilter.setMetadata( "parentDivID", "myDiv" );

// The filter to read image from URL
var url2ImgFilter = new pixpipe.UrlImageReader();

// the image is loaded...
// here, filter = url2ImgFilter
url2ImgFilter.on( "imageLoaded", function(filter){

var forEachPixelFilter = new pixpipe.ForEachPixelImageFilter();

// add the input input
forEachPixelFilter.addInput( url2ImgFilter.getOutput() );

// Apply this treatment to each pixel of the image.
// args:
// position: 2D position of current pixel as an Object {x, y}
// color: array of colors of the current pixel.
//
// Must return, or null to not modify the current color,
// or an array of the same size of color.
forEachPixelFilter.on( "pixel", function(position, color){
return [
color[1], // red (takes the values from green)
color[0], // green (takes the values from red)
color[2] * 0.5, // blue get 50% darker
255 // alpha, at max
]
});

// run the filter
forEachPixelFilter.update();

// use the output of the UrlImageReader as the input for CanvasImageWriter
imageToCanvasFilter.addInput( forEachPixelFilter.getOutput() );
// actually copy the data from the Image2D into the inner HTML5 canvas
imageToCanvasFilter.update();
});

// the input of this reader is a simple string url. Can be local of distant, but if distant, the server must allow CORS.
url2ImgFilter.addInput( "images/sd.jpg" );

// Ask to fetch the image from URL
url2ImgFilter.update();


</script>

</body>
</html>
3 changes: 2 additions & 1 deletion examples/image2DToCanvas.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
var myImage = new pixpipe.Image2D({width: 100, height: 250, color: [255, 128, 64, 255]})

// create a filter to write the image into a canvas
var imageToCanvasFilter = new pixpipe.CanvasImageWriter( "myDiv" );
var imageToCanvasFilter = new pixpipe.CanvasImageWriter( );
imageToCanvasFilter.setMetadata( "parentDivID", "myDiv" );
imageToCanvasFilter.addInput( myImage );
imageToCanvasFilter.update();

Expand Down
27 changes: 12 additions & 15 deletions examples/urlToImage2D.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,24 @@
<script>

// create a filter to write the image into a canvas
var imageToCanvasFilter = new pixpipe.CanvasImageWriter( "myDiv" );
var imageToCanvasFilter = new pixpipe.CanvasImageWriter();
imageToCanvasFilter.setMetadata( "parentDivID", "myDiv" );

// The filter to read image from URL
var url2ImgFilter = new pixpipe.UrlImageReader(

// the image is loaded...
// here, filter = url2ImgFilter
function(filter){

// use the output of the UrlImageReader as the input for CanvasImageWriter
imageToCanvasFilter.addInput( filter.getOutput() );

// actually copy the data from the Image2D into the inner HTML5 canvas
imageToCanvasFilter.update();

}
);
var url2ImgFilter = new pixpipe.UrlImageReader();

// the input of this reader is a simple string url. Can be local of distant, but if distant, the server must allow CORS.
url2ImgFilter.addInput( "images/sd.jpg" );

// the image is loaded...
// here, filter = url2ImgFilter
url2ImgFilter.on("imageLoaded", function( filter ){
// use the output of the UrlImageReader as the input for CanvasImageWriter
imageToCanvasFilter.addInput( filter.getOutput() );
// actually copy the data from the Image2D into the inner HTML5 canvas
imageToCanvasFilter.update();
})

// Ask to fetch the image from URL
url2ImgFilter.update();

Expand Down
14 changes: 14 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,24 @@ Pixpipe.js is an attempt of building an image processing pipeline entirely in Ja

The concept of *pipeline* implies that the output of a `Filter` can be used as input for the next one, like in *ITK*. In Pixpipe.js, this is done by using the `Filter`'s methods `addInput()` and `getOuput()`. Some `Filter` may have several *input* or *output* of different kinds.

# Motivations
To make image processing:
- accessible, using just a web browser and a text pad
- with no other dependency than `pixpipe.js`
- with no required compilation or system fuss
- modular
- generic enough to use different kind of data/datasource
- easy to contribute
- well documented for both users and contributors.


# The future of Pixpipe.js
The plan is to add more image processing filters and tools, like *FFT*, or *wavelet decomposition* to process data in the frequency domain. Though, this kind of processing is quite greedy and would need a *low-level* approach. This can be done efficiently using *C/C++* code converted into optimal lower-level Javascript using [Emscriptem](http://kripken.github.io/emscripten-site/). These are the next big steps.

# License
MIT - See [LICENSE file](LICENSE).


# Todo
## doc for dev
- how to make _inputValidator (Filter) and when to call validateInput
35 changes: 30 additions & 5 deletions src/core/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class Filter extends PixpipeObject {
super();
this._type = Filter.TYPE();

this._isInputValid = false;
// a bunch of event to be defined. Empty by default.
this._events = {};

this._inputValidator = {};

this._input = {
"0": []
Expand Down Expand Up @@ -109,11 +112,25 @@ class Filter extends PixpipeObject {


/**
* MUST be implemented by the class that inherit this.
* MUST change the value of this._isInputValid
* Validate the input data using a model defined in _inputValidator.
* Every class that implement Filter must implement their own _inputValidator.
* Not mandatory to use, still a good practice.
*/
validateInput(){
console.warn("The update() method has not been written, input integrity are not checked.");
hasValidInput(){
var that = this;
var inputCategories = Object.keys( this._inputValidator );

var valid = true;

inputCategories.forEach( function(key){
valid = valid && that._getInput( key ).isOfType( that._inputValidator[ key ] )
});

if(!valid){
console.warn("The input is not valid.");
}

return valid;
}


Expand All @@ -126,6 +143,14 @@ class Filter extends PixpipeObject {
}


/**
* Defines a callback. By defautl, no callback is called.
*/
on(eventId, callback){
this._events[ eventId ] = callback;
}


} /* END class Filter */

export { Filter }
41 changes: 39 additions & 2 deletions src/core/Image2D.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Image2D extends PixpipeObject{
*/
clone(){
var cpImg = new Image2D();
cpImg.setData( this._data.slice(), this._width, this._height );
cpImg.setData( this._data, this._width, this._height );
return cpImg;
}

Expand Down Expand Up @@ -101,23 +101,60 @@ class Image2D extends PixpipeObject{


/**
* @return {Number}
* @return {Number} the width of the Image2D
*/
getWidth(){
return this._width;
}


/**
* @return {Number} the height of the Image2D
*/
getHeight(){
return this._height;
}


/**
* @return {Number} the number of components per pixel
*/
getComponentsPerPixel(){
return this._componentsPerPixel;
}


/**
* @return {Float32Array} the original data, dont mess up with this one.
* in case of doubt, use getDataCopy()
*/
getData(){
//return this._data.slice(); // return a copy
return this._data; // return the actual array, editable!
}


/**
* @return {Float32Array} a deep copy of the data
*/
getDataCopy(){
return this._data.slice();
}


/**
* Compute the (x, y) position from a position in a 1D array.
* @param {Number} i - the index of a pixel. This has nothing to do with
* the number of components per pixel.
* @return {Object} coordinate as {x, y}
*/
get2dPositionFrom1dIndex( i ){
return {
x: i % this._width,
y: Math.floor(i / this._width)
}
}

} /* END of class Image2D */

export { Image2D }
28 changes: 28 additions & 0 deletions src/core/ImageToImageFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Author Jonathan Lurie - http://me.jonahanlurie.fr
* License MIT
* Link https://github.com/jonathanlurie/pixpipejs
* Lab MCIN - Montreal Neurological Institute
*/

import { Filter } from './Filter.js';
import { Image2D } from './Image2D.js';

/**
* ImageToImageFilter is not to be used as-is but rather as a base class for any
* filter that input a single Image2D and output a single Image2D.
* This class does not overload the update() method.
*/
class ImageToImageFilter extends Filter {

constructor(){
super();
this._inputValidator[ 0 ] = Image2D.TYPE();

// will be a copy of the input Image2D buffer
this._inputBuffer = null;
}

} /* END class ImageToImageFilter */

export { ImageToImageFilter }
Loading

0 comments on commit 47101cc

Please sign in to comment.