imagemagick-stream
Advanced tools
Comparing version 1.1.0 to 2.0.0
473
index.js
var PassThrough = require('stream').PassThrough; | ||
var spawn = require('child_process').spawn | ||
var isError = require('util').isError; | ||
var spawn = require('child_process').spawn; | ||
var Duplex = require('reduplexer'); | ||
var util = require('util'); | ||
var isError = util.isError; | ||
var inherit = util.inherits; | ||
var fs = require('fs'); | ||
@@ -22,225 +24,272 @@ | ||
if (!(this instanceof ImageMagick)) return new ImageMagick(src); | ||
this.input = '-'; | ||
this.output = '-'; | ||
this.args = []; | ||
this._operations = []; | ||
this._settings = []; | ||
this.spawn = this.spawn.bind(this); | ||
this.onerror = this.onerror.bind(this); | ||
this.in = new PassThrough(); | ||
this.out = new PassThrough(); | ||
Duplex.call(this, this.in, this.out); | ||
if (src) this.from(src); | ||
setImmediate(this.spawn); | ||
} | ||
ImageMagick.prototype = { | ||
__proto__: Duplex.prototype, | ||
/** | ||
* Sets the input file format | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
inputFormat: function (args) { | ||
this.input = args + ':-'; | ||
return this; | ||
}, | ||
/** | ||
* Sets the output file format | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
outputFormat: function (args) { | ||
this.output = args + ':-'; | ||
return this; | ||
}, | ||
/** | ||
* Sets the `quality` option | ||
* | ||
* @param {String|Number} args | ||
* @api public | ||
*/ | ||
quality: function (args) { | ||
this.args.push('-quality', args); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `resize` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
resize: function (args) { | ||
this.args.push('-resize', args); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `scale` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
scale: function (args) { | ||
this.args.push('-scale', args); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `crop` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
crop: function (args) { | ||
this.args.push('-crop', args); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `gravity` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
gravity: function (args) { | ||
this.args.push('-gravity', args); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `thumbnail` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
thumbnail: function (args) { | ||
this.args.push('-thumbnail', args); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `auto-orient` option | ||
* | ||
* @api public | ||
*/ | ||
autoOrient: function () { | ||
this.args.push('-auto-orient'); | ||
return this; | ||
}, | ||
/** | ||
* Sets the `type` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
type: function (args) { | ||
this.args.push('-type', args); | ||
return this; | ||
}, | ||
/** | ||
* Passes additional arguments | ||
* | ||
* @param {Object} options | ||
* @api public | ||
*/ | ||
options: function (options) { | ||
Object.keys(options).forEach(function (key) { | ||
var val = options[key]; | ||
this.args.push('-' + key); | ||
if (val != null) this.args.push(val); | ||
}, this); | ||
return this; | ||
}, | ||
/** | ||
* Inherit from `Duplex` | ||
*/ | ||
/** | ||
* Read image data from path | ||
* | ||
* @param {String} path | ||
* @api public | ||
*/ | ||
from: function (path) { | ||
var read = fs.createReadStream(path); | ||
read.on('error', this.onerror); | ||
read.pipe(this); | ||
return this; | ||
}, | ||
/** | ||
* Write image data to path | ||
* | ||
* @param {String} path | ||
* @api public | ||
*/ | ||
to: function (path) { | ||
var write = fs.createWriteStream(path); | ||
write.on('error', this.onerror); | ||
this.pipe(write); | ||
return this; | ||
}, | ||
/** | ||
* Spawn `convert` | ||
* | ||
* @api private | ||
*/ | ||
spawn: function () { | ||
this.args.push(this.output); | ||
this.args.unshift(this.input); | ||
var proc = spawn('convert', this.args); | ||
var stdin = proc.stdin; | ||
stdin.on('error', this.onerror); | ||
this.in.pipe(stdin); | ||
var stdout = proc.stdout; | ||
stdout.on('error', this.onerror); | ||
stdout.pipe(this.out); | ||
var stderr = proc.stderr; | ||
stderr.on('data', this.onerror); | ||
stderr.on('error', this.onerror); | ||
this.emit('spawn', proc); | ||
}, | ||
/** | ||
* Re-emit errors | ||
* | ||
* @param {Error|Buffer} err | ||
* @api private | ||
*/ | ||
onerror: function (err) { | ||
if (!isError(err)) err = new Error(err); | ||
if (!this.listeners('error')) throw err; | ||
this.emit('error', err); | ||
inherit(ImageMagick, Duplex); | ||
/** | ||
* Sets the input file format | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.inputFormat = function (args) { | ||
this.input = args + ':-'; | ||
return this; | ||
}, | ||
/** | ||
* Sets the output file format | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.outputFormat = function (args) { | ||
this.output = args + ':-'; | ||
return this; | ||
}; | ||
/** | ||
* Sets the `quality` option | ||
* | ||
* @param {String|Number} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.quality = function (args) { | ||
this._operations.push('-quality', args); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `resize` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.resize = function (args) { | ||
this._operations.push('-resize', args); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `scale` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.scale = function (args) { | ||
this._operations.push('-scale', args); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `crop` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.crop = function (args) { | ||
this._operations.push('-crop', args); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `gravity` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.gravity = function (args) { | ||
this._operations.push('-gravity', args); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `thumbnail` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.thumbnail = function (args) { | ||
this._operations.push('-thumbnail', args); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `auto-orient` option | ||
* | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.autoOrient = function () { | ||
this._operations.push('-auto-orient'); | ||
return this; | ||
}; | ||
/** | ||
* Sets the `type` option | ||
* | ||
* @param {String} args | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.type = function (args) { | ||
this._operations.push('-type', args); | ||
return this; | ||
}; | ||
/** | ||
* Passes additional settings | ||
* | ||
* @param {String|Object} key | ||
* @param {Mixed} val | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.settings = | ||
ImageMagick.prototype.set = function (key, val) { | ||
this.freehand('_settings', key, val); | ||
return this; | ||
} | ||
/** | ||
* Passes additional operations | ||
* | ||
* @param {String|Object} key | ||
* @param {Mixed} val | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.operations = | ||
ImageMagick.prototype.op = function (key, val) { | ||
this.freehand('_operations', key, val); | ||
return this; | ||
}; | ||
/** | ||
* Read image data from path | ||
* | ||
* @param {String} path | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.from = function (path) { | ||
var read = fs.createReadStream(path); | ||
read.on('error', this.onerror); | ||
read.pipe(this); | ||
return this; | ||
}; | ||
/** | ||
* Write image data to path | ||
* | ||
* @param {String} path | ||
* @api public | ||
*/ | ||
ImageMagick.prototype.to = function (path) { | ||
var write = fs.createWriteStream(path); | ||
write.on('error', this.onerror); | ||
this.pipe(write); | ||
return this; | ||
}; | ||
/** | ||
* Spawn `convert` | ||
* | ||
* @api private | ||
*/ | ||
ImageMagick.prototype.spawn = function () { | ||
var proc = spawn('convert', this.args()); | ||
var stdin = proc.stdin; | ||
stdin.on('error', this.onerror); | ||
this.in.pipe(stdin); | ||
var stdout = proc.stdout; | ||
stdout.on('error', this.onerror); | ||
stdout.pipe(this.out); | ||
var stderr = proc.stderr; | ||
stderr.on('data', this.onerror); | ||
stderr.on('error', this.onerror); | ||
this.emit('spawn', proc); | ||
}; | ||
/** | ||
* Helper for freehand settings and operations | ||
* | ||
* @param {String} key | ||
* @param {String|Object} obj | ||
* @param {Mixed} [val] | ||
* @api private | ||
*/ | ||
ImageMagick.prototype.freehand = function (key, op, val) { | ||
var self = this; | ||
if (typeof op == 'string') { | ||
return push(key, op, val); | ||
} | ||
Object.keys(op).forEach(function (prop) { | ||
push(key, prop, op[prop]); | ||
}); | ||
function push (key, op, val) { | ||
self[key].push('-' + op); | ||
if (val != null) self[key].push(val); | ||
} | ||
}; | ||
/** | ||
* Constructs args for cli call | ||
* | ||
* @api private | ||
*/ | ||
ImageMagick.prototype.args = function() { | ||
return this._settings.concat([this.input], this._operations, [this.output]); | ||
} | ||
/** | ||
* Re-emit errors | ||
* | ||
* @param {Error|Buffer} err | ||
* @api private | ||
*/ | ||
ImageMagick.prototype.onerror = function (err) { | ||
if (!isError(err)) err = new Error(err); | ||
if (!this.listeners('error')) throw err; | ||
this.emit('error', err); | ||
}; |
{ | ||
"name": "imagemagick-stream", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "Streaming Imagemagick api", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -5,3 +5,4 @@ # imagemagick-stream | ||
[![Build Status](https://travis-ci.org/eivindfjeldstad/imagemagick-stream.svg?branch=master)](https://travis-ci.org/eivindfjeldstad/imagemagick-stream) | ||
[![npm version](http://img.shields.io/npm/v/imagemagick-stream.svg?style=flat)](https://npmjs.org/package/imagemagick-stream) | ||
[![Build Status](http://img.shields.io/travis/eivindfjeldstad/imagemagick-stream.svg?style=flat)](https://travis-ci.org/eivindfjeldstad/imagemagick-stream) | ||
@@ -15,7 +16,7 @@ ## Use | ||
var out = fs.createWriteStream('image-resized.png'); | ||
var resize = im().resize('200x200').quality(90); | ||
in.pipe(resize).pipe(out); | ||
// Alternatively | ||
@@ -26,3 +27,3 @@ im('image.png') | ||
.pipe(out); | ||
// Or | ||
@@ -34,16 +35,16 @@ im('image.png') | ||
``` | ||
For freehand arguments, use `.options()` | ||
For freehand settings and operations, use `.op()` and `.set()`. | ||
See the [imagemagick docs](http://www.imagemagick.org/script/convert.php) a list of available options. | ||
``` js | ||
im('image.png') | ||
.set('density', 400) | ||
.set('channel', 'RGB') | ||
.resize('200x200') | ||
.quality(90) | ||
.options({ | ||
'strip': undefined, | ||
'gaussian-blur': 0.05, | ||
'interlace': 'Plane' | ||
}); | ||
.op('gaussian-blur', 0.05); | ||
``` | ||
## License | ||
## License | ||
MIT |
@@ -6,16 +6,11 @@ var assert = require('assert'); | ||
describe('im()', function () { | ||
it('should have an .args property', function () { | ||
var img = im(); | ||
assert(Array.isArray(img.args)); | ||
assert(img.args.length == 0); | ||
}); | ||
it('should have an .input property', function () { | ||
assert(im().input == '-'); | ||
}); | ||
it('should have an .output property', function () { | ||
assert(im().output == '-'); | ||
}); | ||
it('should be pipe-able', function (done) { | ||
@@ -31,3 +26,3 @@ var img = im(); | ||
}); | ||
it('should emit errors from stderr', function (done) { | ||
@@ -38,7 +33,7 @@ var img = im(); | ||
img.on('error', function (err) { | ||
assert(/^convert\:/.test(err.message)); | ||
assert(/^convert/.test(err.message)); | ||
done(); | ||
}); | ||
}); | ||
describe('.from()', function () { | ||
@@ -55,3 +50,3 @@ it('should read from the given path', function (done) { | ||
}); | ||
describe('.to()', function () { | ||
@@ -68,3 +63,3 @@ it('should write to the given path', function (done) { | ||
}); | ||
describe('.spawn()', function () { | ||
@@ -78,111 +73,192 @@ it('should call .spawn() with setImmediate', function (done) { | ||
}); | ||
it('should add input and output format to .args', function (done) { | ||
it('should add input and output format to args', function (done) { | ||
var img = im(); | ||
img.on('spawn', function () { | ||
assert(img.input == img.args[0]); | ||
assert(img.output == img.args[img.args.length - 1]); | ||
done(); | ||
}); | ||
var args = img.args(); | ||
assert.equal(img.input, args[0]); | ||
assert.equal(img.output, args[args.length - 1]); | ||
done(); | ||
}); | ||
}); | ||
describe('.quality()', function () { | ||
it('should set the quality option', function () { | ||
var img = im().quality(90); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-quality'); | ||
assert(img.args[1] == '90'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-quality'); | ||
assert(args[2] == '90'); | ||
}); | ||
}); | ||
describe('.resize()', function () { | ||
it('should set the resize option', function () { | ||
var img = im().resize('200x200'); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-resize'); | ||
assert(img.args[1] == '200x200'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-resize'); | ||
assert(args[2] == '200x200'); | ||
}); | ||
}); | ||
describe('.scale()', function () { | ||
it('should set the scale option', function () { | ||
var img = im().scale('200x200'); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-scale'); | ||
assert(img.args[1] == '200x200'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-scale'); | ||
assert(args[2] == '200x200'); | ||
}); | ||
}); | ||
describe('.crop()', function () { | ||
it('should set the crop option', function () { | ||
var img = im().crop('200x200'); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-crop'); | ||
assert(img.args[1] == '200x200'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-crop'); | ||
assert(args[2] == '200x200'); | ||
}); | ||
}); | ||
describe('.gravity()', function () { | ||
it('should set the gravity option', function () { | ||
var img = im().gravity('North'); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-gravity'); | ||
assert(img.args[1] == 'North'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-gravity'); | ||
assert(args[2] == 'North'); | ||
}); | ||
}); | ||
describe('.thumbnail()', function () { | ||
it('should set the thumbnail option', function () { | ||
var img = im().thumbnail('200x200'); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-thumbnail'); | ||
assert(img.args[1] == '200x200'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-thumbnail'); | ||
assert(args[2] == '200x200'); | ||
}); | ||
}); | ||
describe('.autoOrient()', function () { | ||
it('should set the auto-orient option', function () { | ||
var img = im().autoOrient(); | ||
assert(img.args.length == 1); | ||
assert(img.args[0] == '-auto-orient'); | ||
var args = img.args(); | ||
assert(args.length == 3); | ||
assert(args[1] == '-auto-orient'); | ||
}); | ||
}); | ||
describe('.type()', function () { | ||
it('should set the type option', function () { | ||
var img = im().type('jpg'); | ||
assert(img.args.length == 2); | ||
assert(img.args[0] == '-type'); | ||
assert(img.args[1] == 'jpg'); | ||
var args = img.args(); | ||
assert(args.length == 4); | ||
assert(args[1] == '-type'); | ||
assert(args[2] == 'jpg'); | ||
}); | ||
}); | ||
describe('.inputFormat()', function () { | ||
it('should set the input format', function () { | ||
var img = im().inputFormat('test'); | ||
assert(img.input == 'test:-'); | ||
var args = img.args(); | ||
assert(args[0] == 'test:-'); | ||
}); | ||
}); | ||
describe('.outputFormat()', function () { | ||
it('should set the output format', function () { | ||
var img = im().outputFormat('test'); | ||
assert(img.output == 'test:-'); | ||
var args = img.args(); | ||
assert(args[1] == 'test:-'); | ||
}); | ||
}); | ||
describe('.options()', function () { | ||
it('should allow freehand arguments', function () { | ||
var img = im().options({ | ||
describe('.op()', function () { | ||
it('should accept a key-value pair', function () { | ||
var img = im(); | ||
img.op('gaussian-blur', 0.05); | ||
img.op('interlace', 'Plane'); | ||
var args = img.args(); | ||
assert(args[1] == '-gaussian-blur'); | ||
assert(args[2] == '0.05'); | ||
assert(args[3] == '-interlace'); | ||
assert(args[4] == 'Plane'); | ||
}); | ||
it('should accept an object', function () { | ||
var img = im().op({ | ||
'gaussian-blur': 0.05, | ||
'interlace': 'Plane' | ||
}); | ||
assert(img.args[0] == '-gaussian-blur'); | ||
assert(img.args[1] == '0.05'); | ||
assert(img.args[2] == '-interlace'); | ||
assert(img.args[3] == 'Plane'); | ||
var args = img.args(); | ||
assert(args[1] == '-gaussian-blur'); | ||
assert(args[2] == '0.05'); | ||
assert(args[3] == '-interlace'); | ||
assert(args[4] == 'Plane'); | ||
}); | ||
}); | ||
describe('.operations()', function () { | ||
it('should alias .op()', function () { | ||
var img = im(); | ||
assert(img.op === img.operations); | ||
}); | ||
}); | ||
describe('.set()', function() { | ||
it('should accept a key-value pair', function() { | ||
var img = im(); | ||
img.set('density', 500) | ||
img.set('channel', 'RGB'); | ||
var args = img.args(); | ||
assert(args[0] == '-density'); | ||
assert(args[1] == 500); | ||
assert(args[2] == '-channel'); | ||
assert(args[3] == 'RGB'); | ||
assert(args[4] == '-'); | ||
assert(args[5] == '-'); | ||
}); | ||
it('should accept an object', function() { | ||
var img = im().set({ | ||
'density': 500, | ||
'channel': 'RGB' | ||
}); | ||
var args = img.args(); | ||
assert(args[0] == '-density'); | ||
assert(args[1] == 500); | ||
assert(args[2] == '-channel'); | ||
assert(args[3] == 'RGB'); | ||
assert(args[4] == '-'); | ||
assert(args[5] == '-'); | ||
}); | ||
it('should be combinable with freehand operations', function() { | ||
var img = im(); | ||
img.set('density', 500); | ||
img.op('gaussian-blur', 0.05); | ||
var args = img.args(); | ||
assert(args[0] == '-density'); | ||
assert(args[1] == 500); | ||
assert(args[2] == '-'); | ||
assert(args[3] == '-gaussian-blur'); | ||
assert(args[4] == 0.05); | ||
assert(args[5] == '-'); | ||
}); | ||
}); | ||
describe('.settings()', function () { | ||
it('should alias .set()', function () { | ||
var img = im(); | ||
assert(img.set === img.settings); | ||
}) | ||
}) | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43920
465
47