Socket
Socket
Sign inDemoInstall

image-filter-core

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

image-filter-core - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0

contributing.json

9

package.json
{
"name": "image-filter-core",
"version": "1.0.0",
"version": "2.0.0",
"description": "Core module for image-filter",
"main": "src/index.js",
"scripts": {
"test": "./node_modules/.bin/karma start",
"eslint": "eslint src/**/*.js",
"test": "karma start",
"codecov": "cat coverage/*/lcov.info | codecov",

@@ -35,2 +36,3 @@ "serve": "http-server sandbox"

"codecov.io": "^0.1.6",
"eslint": "^3.13.0",
"http-server": "^0.9.0",

@@ -52,5 +54,4 @@ "karma": "^0.13.22",

"dependencies": {
"es6-promise": "^4.0.5",
"webworkify": "^1.2.1"
"es6-promise": "^4.0.5"
}
}

@@ -6,5 +6,17 @@ ![build status](https://travis-ci.org/canastro/image-filter-threshold.svg?branch=master)

# image-filter-core
Core module used by image-filter's modules that exports helper functions.
Small library that relies on webworkers to apply image transformations.
There are several modules that use `image-filter-core`, such as:
* [image-filters](https://www.npmjs.com/package/image-filters)
* [image-filter-brightness](https://www.npmjs.com/package/image-filter-brightness)
* [image-filter-contrast](https://www.npmjs.com/package/image-filter-contrast)
* [image-filter-grayscale](https://www.npmjs.com/package/image-filter-grayscale)
* [image-filter-threshold](https://www.npmjs.com/package/image-filter-threshold)
* [image-filter-sepia](https://www.npmjs.com/package/image-filter-sepia)
* [image-filter-invert](https://www.npmjs.com/package/image-filter-invert)
* [image-filter-gamma](https://www.npmjs.com/package/image-filter-gamma)
* [image-filter-colorize](https://www.npmjs.com/package/image-filter-colorize)
But you can easily create your own transformation function and rely on `image-filter-core` to handle the webworkers and to split the work.
## Install

@@ -16,5 +28,5 @@ ```

## Methods
### getCanvas
### # getCanvas()
It returns a canvas with the given width and height
```
```js
var imageFilterCore = require('image-filter-core');

@@ -24,5 +36,5 @@ var canvas = imageFilterCore.getCanvas(100, 100);

### convertImageDataToCanvasURL
### # convertImageDataToCanvasURL()
Given a ImageData it returns the dataURL
```
```js
var imageFilterCore = require('image-filter-core');

@@ -32,17 +44,26 @@ var canvasURL = imageFilterCore.convertImageDataToCanvasURL(imageData);

### apply
Given a worker file with the transformation the work is split between the configured number of workers and the transformation is applied returning a Promise
### # apply()
Provide the ImageData, the transformation function, the options to be passed to the transformation function and the number of workers to split the work.
```
var webworkify = require('webworkify');
```js
var imageFilterCore = require('image-filter-core');
var worker = require('./transformation-worker');
var imageData = imageFilterCore.apply(
worker,
nWorkers,
canvas,
context,
params
);
imageFilterCore.apply(data, transform, options, nWorkers)
.then(function (imageData) {
// Do whatever you want with imageData
});
```
The transform function receives ImageData, the length of data to transform and the options that the developer provided to image-fiter-core, example transformation function for the threshold effect:
```js
function transform (data, length, options) {
for (var i = 0; i < length; i += 4) {
var r = data[i];
var g = data[i + 1];
var b = data[i + 2];
var v = (0.2126 * r + 0.7152 * g + 0.0722 * b >= options.threshold) ? 255 : 0;
data[i] = data[i + 1] = data[i + 2] = v;
}
}
```
require('es6-promise/auto');
var work = require('webworkify');
var worker = require('./worker');
/**
* It returns a canvas with the given width and height
* @name getCanvas
* @param {Number} w - width
* @param {Number} h - height
* @returns {Object}
*/
exports.getCanvas = function (w, h) {
* It returns a canvas with the given width and height
* @name getCanvas
* @param {Number} w - width
* @param {Number} h - height
* @returns {Object}
*/
function getCanvas(w, h) {
var canvas = document.createElement('canvas');

@@ -17,11 +17,11 @@ canvas.width = w;

return canvas;
};
}
/**
* Given a ImageData it returns the dataURL
* @name convertImageDataToCanvasURL
* @param {ImageData} imageData
* @returns {String}
*/
exports.convertImageDataToCanvasURL = function (imageData) {
* Given a ImageData it returns the dataURL
* @name convertImageDataToCanvasURL
* @param {ImageData} imageData
* @returns {String}
*/
function convertImageDataToCanvasURL(imageData) {
var canvas = document.createElement('canvas');

@@ -34,19 +34,57 @@ var ctx = canvas.getContext('2d');

return canvas.toDataURL();
};
}
/**
* Transforms the body of a function into a string
* This is used to require the worker function and create a new Blob
* @method extractBodyFunction
* @param {Function} fn
* @returns {String}
*/
function extractBodyFunction(fn) {
return fn.toString().trim().match(
/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/
)[1];
}
/**
* Given a worker file with the transformation the work is split
* between the configured number of workers and the transformation is applied
* returning a Promise
* @name apply
* @param {Object} worker
* @param {Number} nWorkers
* @param {Object} canvas
* @param {Object} context
* @param {Number} params
* @returns {Promise}
* Creates a Worker from the contents in ./worker.js
* @method createWorker
* @returns {Worker}
*/
exports.apply = function (worker, nWorkers, canvas, context, params) {
var w;
function createWorker() {
var functionBody = extractBodyFunction(worker);
var blob = new Blob([functionBody], { type: 'text/javascript' });
return new Worker(window.URL.createObjectURL(blob));
}
/**
* Creats transformation ObjectURL so that this function
* can be imported in the worker
* @method createTransformation
* @param {Function} transform
* @returns {String}
*/
function createTransformation(transform) {
var blob = new Blob(['' + transform], { type: 'text/javascript' });
return window.URL.createObjectURL(blob);
}
/**
* Given a worker file with the transformation the work is split
* between the configured number of workers and the transformation is applied
* returning a Promise
* @name apply
* @param {Function} worker
* @param {Number} options
* @returns {Promise}
*/
function apply(data, transform, options, nWorkers) {
var w = createWorker();
var transformationURL = createTransformation(transform);
var canvas = getCanvas(data.width, data.height);
var context = canvas.getContext('2d');
var finished = 0;

@@ -57,2 +95,5 @@ var len = canvas.width * canvas.height * 4;

// Drawing the source image into the target canvas
context.putImageData(data, 0, 0);
// Minimum number of workers = 1

@@ -68,3 +109,2 @@ if (!nWorkers) {

for (var index = 0; index < nWorkers; index++) {
w = work(worker);

@@ -93,9 +133,16 @@ w.addEventListener('message', function (e) {

w.postMessage({
data: canvasData,
canvasData: canvasData,
index: index,
length: segmentLength,
params: params
options: options,
transformationURL: transformationURL
});
}
});
}
module.exports = {
apply: apply,
convertImageDataToCanvasURL: convertImageDataToCanvasURL,
getCanvas: getCanvas
};
const expect = require('chai').expect;
const sinon = require('sinon');
const proxyquire = require('proxyquireify')(require);
const imageFilterCore = require('../src/index');
describe('utils', function () {
describe('index', function () {
var sandbox;

@@ -17,4 +17,3 @@ before(function () {

it('should return a canvas of 100 x 100', function () {
const utils = require('../src/index');
const element = utils.getCanvas(100, 100);
const element = imageFilterCore.getCanvas(100, 100);

@@ -29,3 +28,2 @@ expect(element.tagName).to.equal('CANVAS');

it('should create canvas and call toDataURL', function () {
const utils = require('../src/index');
const expectedResult = 'TEST';

@@ -49,3 +47,3 @@

const result = utils.convertImageDataToCanvasURL(imageData);
const result = imageFilterCore.convertImageDataToCanvasURL(imageData);

@@ -65,7 +63,14 @@ expect(document.createElement.calledWith('canvas')).to.equal(true);

var eventListenerCallback;
const expectedResult = 'TEST';
const worker = {
addEventListener: function addEventListener(evt, fn) {
eventListenerCallback = fn;
},
postMessage: sandbox.stub()
};
const transform = sandbox.stub();
const ctx = {
putImageData: sandbox.stub(),
getImageData: sandbox.stub()
getImageData: sandbox.stub(),
putImageData: sandbox.stub()
};

@@ -75,25 +80,18 @@

getContext: sandbox.stub().returns(ctx),
toDataURL: sandbox.stub().returns(expectedResult)
toDataURL: sandbox.stub().returns()
};
const worker = {
addEventListener: function addEventListener(evt, fn) {
eventListenerCallback = fn;
},
postMessage: sandbox.stub()
};
const data = { width: 100, height: 200 };
const nWorkers = 4;
const options = { test: 'DUMMY-OPTION' };
const utils = proxyquire('../src/index', {
'webworkify': function () { return worker; }
});
window.Worker = sandbox.stub().returns(worker);
sandbox.stub(window.URL, 'createObjectURL');
sandbox.stub(document, 'createElement').returns(canvas);
const nWorkers = 4;
const result = imageFilterCore.apply(data, transform, options, nWorkers);
const result = utils.apply(
'DUMMY',
nWorkers,
canvas,
ctx,
{}
);
// Two object urls created, one for the worker one for the transform function
expect(window.URL.createObjectURL.calledTwice).to.equal(true);
expect(window.Worker.calledOnce).to.equal(true);

@@ -110,4 +108,6 @@ const evt = { data: { result: 'DUMMY', index: 1 } };

// One for the intial render and One for each worker
expect(ctx.putImageData.callCount).to.equal(nWorkers + 1);
// One for each worker
expect(ctx.putImageData.callCount).to.equal(nWorkers);
expect(worker.postMessage.callCount).to.equal(nWorkers);

@@ -122,7 +122,14 @@ done();

var eventListenerCallback;
const expectedResult = 'TEST';
const worker = {
addEventListener: function addEventListener(evt, fn) {
eventListenerCallback = fn;
},
postMessage: sandbox.stub()
};
const transform = sandbox.stub();
const ctx = {
putImageData: sandbox.stub(),
getImageData: sandbox.stub()
getImageData: sandbox.stub(),
putImageData: sandbox.stub()
};

@@ -132,25 +139,18 @@

getContext: sandbox.stub().returns(ctx),
toDataURL: sandbox.stub().returns(expectedResult)
toDataURL: sandbox.stub().returns()
};
const worker = {
addEventListener: function addEventListener(evt, fn) {
eventListenerCallback = fn;
},
postMessage: sandbox.stub()
const options = {
data: { width: 100, height: 200 }
};
const utils = proxyquire('../src/index', {
'webworkify': function () { return worker; }
});
window.Worker = sandbox.stub().returns(worker);
sandbox.stub(window.URL, 'createObjectURL');
sandbox.stub(document, 'createElement').returns(canvas);
const nWorkers = 0;
const result = imageFilterCore.apply(transform, options);
const result = utils.apply(
'DUMMY',
nWorkers,
canvas,
ctx,
{}
);
// Two object urls created, one for the worker one for the transform function
expect(window.URL.createObjectURL.calledTwice).to.equal(true);
expect(window.Worker.calledOnce).to.equal(true);

@@ -164,4 +164,6 @@ const evt = { data: { result: 'DUMMY', index: 1 } };

// One for the intial render and One for each worker
expect(ctx.putImageData.callCount).to.equal(2);
// One for each worker
expect(ctx.putImageData.callCount).to.equal(1);
expect(worker.postMessage.callCount).to.equal(1);

@@ -168,0 +170,0 @@ done();

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc