Add support for Promises/A+ #33

This commit is contained in:
Lovell Fuller 2014-06-01 11:27:30 +01:00
parent 9a05684302
commit 7319533969
4 changed files with 68 additions and 34 deletions

View File

@ -9,7 +9,7 @@
The typical use case for this high speed Node.js module is to convert large images of many formats to smaller, web-friendly JPEG, PNG and WebP images of varying dimensions. The typical use case for this high speed Node.js module is to convert large images of many formats to smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
The performance of JPEG resizing is typically 8x faster than ImageMagick and GraphicsMagick, based mainly on the number of CPU cores available. Everything remains non-blocking thanks to _libuv_. The performance of JPEG resizing is typically 8x faster than ImageMagick and GraphicsMagick, based mainly on the number of CPU cores available. Everything remains non-blocking thanks to _libuv_ and Promises/A+ are supported.
This module supports reading and writing images of JPEG, PNG and WebP to and from both Buffer objects and the filesystem. It also supports reading images of many other types from the filesystem via libmagick++ or libgraphicsmagick++ if present. This module supports reading and writing images of JPEG, PNG and WebP to and from both Buffer objects and the filesystem. It also supports reading images of many other types from the filesystem via libmagick++ or libgraphicsmagick++ if present.
@ -94,19 +94,13 @@ sharp('input.jpg').rotate().resize(null, 200).progressive().toBuffer(function(er
``` ```
```javascript ```javascript
sharp('input.png').rotate(180).resize(300).sharpen().quality(90).webp(function(err, outputBuffer) { sharp('input.png').rotate(180).resize(300).sharpen().quality(90).webp().then(function(outputBuffer) {
if (err) {
throw err;
}
// outputBuffer contains 300px wide, upside down, sharpened, 90% quality WebP image data // outputBuffer contains 300px wide, upside down, sharpened, 90% quality WebP image data
}); });
``` ```
```javascript ```javascript
sharp(inputBuffer).resize(200, 300).embedWhite().toFile('output.tiff', function(err) { sharp(inputBuffer).resize(200, 300).embedWhite().toFile('output.tiff').then(function() {
if (err) {
throw err;
}
// output.tiff is a 200 pixels wide and 300 pixels high image containing a scaled // output.tiff is a 200 pixels wide and 300 pixels high image containing a scaled
// version, embedded on a white canvas, of the image data in buffer // version, embedded on a white canvas, of the image data in buffer
}); });
@ -123,10 +117,7 @@ sharp('input.gif').resize(200, 300).embedBlack().webp(function(err, outputBuffer
``` ```
```javascript ```javascript
sharp(inputBuffer).resize(200, 200).max().jpeg(function(err, outputBuffer) { sharp(inputBuffer).resize(200, 200).max().jpeg().then(function(outputBuffer) {
if (err) {
throw err;
}
// outputBuffer contains JPEG image data no wider than 200 pixels and no higher // outputBuffer contains JPEG image data no wider than 200 pixels and no higher
// than 200 pixels regardless of the inputBuffer image dimensions // than 200 pixels regardless of the inputBuffer image dimensions
}); });
@ -205,35 +196,45 @@ An advanced setting for the _zlib_ compression level of the lossless PNG output
An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQUENTIAL`. This will reduce memory usage and can improve performance on some systems. An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQUENTIAL`. This will reduce memory usage and can improve performance on some systems.
### toFile(filename, callback) ### toFile(filename, [callback])
`filename` is a String containing the filename to write the image data to. The format is inferred from the extension, with JPEG, PNG, WebP and TIFF supported. `filename` is a String containing the filename to write the image data to. The format is inferred from the extension, with JPEG, PNG, WebP and TIFF supported.
`callback` is called with a single argument `(err)` containing an error message, if any. `callback`, if present, is called with a single argument `(err)` containing an error message, if any.
### jpeg(callback) A Promises/A+ promise is returned when `callback` is not provided.
### toBuffer([callback])
Write image data to a Buffer, the format of which will match the input image. JPEG, PNG and WebP are supported.
`callback`, if present, gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant image data.
A Promises/A+ promise is returned when `callback` is not provided.
### jpeg([callback])
Write JPEG image data to a Buffer. Write JPEG image data to a Buffer.
`callback` gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant JPEG image data. `callback`, if present, gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant JPEG image data.
A Promises/A+ promise is returned when `callback` is not provided.
### png(callback) ### png(callback)
Write PNG image data to a Buffer. Write PNG image data to a Buffer.
`callback` gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant PNG image data. `callback`, if present, gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant PNG image data.
### webp(callback) A Promises/A+ promise is returned when `callback` is not provided.
### webp([callback])
Write WebP image data to a Buffer. Write WebP image data to a Buffer.
`callback` gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant WebP image data. `callback`, if present, gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant WebP image data.
### toBuffer(callback) A Promises/A+ promise is returned when `callback` is not provided.
Write image data to a Buffer, the format of which will match the input image. JPEG, PNG and WebP are supported.
`callback` gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant image data.
### sharp.cache([limit]) ### sharp.cache([limit])

View File

@ -1,6 +1,7 @@
/*jslint node: true */ /*jslint node: true */
'use strict'; 'use strict';
var Promise = require('bluebird');
var sharp = require('./build/Release/sharp'); var sharp = require('./build/Release/sharp');
var Sharp = function(input) { var Sharp = function(input) {
@ -141,7 +142,7 @@ Sharp.prototype.toFile = function(output, callback) {
if (this.options.fileIn === output) { if (this.options.fileIn === output) {
callback('Cannot use same file for input and output'); callback('Cannot use same file for input and output');
} else { } else {
this._sharp(output, callback); return this._sharp(output, callback);
} }
} }
return this; return this;
@ -166,13 +167,28 @@ Sharp.prototype.webp = function(callback) {
return this._sharp('__webp', callback); return this._sharp('__webp', callback);
}; };
/*
Invoke the C++ image processing pipeline
Supports callback and promise variants
*/
Sharp.prototype._sharp = function(output, callback) { Sharp.prototype._sharp = function(output, callback) {
sharp.resize( if (typeof callback === 'function') {
this.options, // I like callbacks
output, sharp.resize(this.options, output, callback);
callback
);
return this; return this;
} else {
// I like promises
var options = this.options;
return new Promise(function(resolve, reject) {
sharp.resize(options, output, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
}; };
module.exports.cache = function(limit) { module.exports.cache = function(limit) {

View File

@ -1,6 +1,6 @@
{ {
"name": "sharp", "name": "sharp",
"version": "0.4.2", "version": "0.5.0",
"author": "Lovell Fuller <npm@lovell.info>", "author": "Lovell Fuller <npm@lovell.info>",
"contributors": [ "contributors": [
"Pierre Inglebert <pierre.inglebert@gmail.com>" "Pierre Inglebert <pierre.inglebert@gmail.com>"
@ -31,7 +31,8 @@
"buffer" "buffer"
], ],
"dependencies": { "dependencies": {
"nan": "^1.1.0" "nan": "^1.1.2",
"bluebird": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
"imagemagick": "^0.1.3", "imagemagick": "^0.1.3",

View File

@ -1,3 +1,7 @@
/*jslint node: true */
/*jslint es5: true */
'use strict';
var sharp = require("../index"); var sharp = require("../index");
var path = require("path"); var path = require("path");
var imagemagick = require("imagemagick"); var imagemagick = require("imagemagick");
@ -236,6 +240,18 @@ async.series([
done(); done();
}); });
}); });
},
// Promises/A+
function(done) {
sharp(inputJpg).resize(320, 240).toFile(outputJpg).then(function() {
imagemagick.identify(outputJpg, function(err, features) {
assert.strictEqual(320, features.width);
assert.strictEqual(240, features.height);
done();
});
}).catch(function(err) {
throw err;
});
} }
]); ]);