Comparing version
@@ -5,3 +5,4 @@ var sharp = require("./build/Release/sharp"); | ||
jpeg: "__jpeg", | ||
png: "__png" | ||
png: "__png", | ||
webp: "__webp" | ||
}; | ||
@@ -8,0 +9,0 @@ |
{ | ||
"name": "sharp", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"author": "Lovell Fuller", | ||
"description": "High performance module to resize JPEG and PNG images using the libvips image processing library", | ||
"description": "High performance module to resize JPEG, PNG, WebP and TIFF images using the libvips image processing library", | ||
"scripts": { | ||
@@ -17,2 +17,4 @@ "test": "node tests/perf.js" | ||
"png", | ||
"webp", | ||
"tiff", | ||
"resize", | ||
@@ -24,2 +26,3 @@ "thumbnail", | ||
"libvips", | ||
"vips", | ||
"fast", | ||
@@ -26,0 +29,0 @@ "buffer" |
@@ -10,6 +10,8 @@ # sharp | ||
The typical use case for this high speed Node.js module is to convert large JPEG and PNG images to smaller JPEG and PNG images of varying dimensions. | ||
The typical use case for this high speed Node.js module is to convert large JPEG, PNG, WebP and TIFF images to smaller images of varying dimensions. | ||
The performance of JPEG resizing is typically 15x-25x faster than ImageMagick and GraphicsMagick, based mainly on the number of CPU cores available. | ||
This module supports reading and writing images to and from both the filesystem and Buffer objects (TIFF is limited to filesystem only). Everything remains non-blocking thanks to _libuv_. | ||
Under the hood you'll find the blazingly fast [libvips](https://github.com/jcupitt/libvips) image processing library, originally created in 1989 at Birkbeck College and currently maintained by John Cupitt. | ||
@@ -36,5 +38,5 @@ | ||
`input` can either be a filename String or a Buffer. When using a filename libvips will `mmap` the file for improved performance. | ||
`input` can either be a filename String or a Buffer. | ||
`output` can either be a filename String or one of `sharp.buffer.jpeg` or `sharp.buffer.png` to pass a Buffer containing image data to `callback`. | ||
`output` can either be a filename String or one of `sharp.buffer.jpeg`, `sharp.buffer.png` or `sharp.buffer.webp` to pass a Buffer containing JPEG, PNG or WebP image data to `callback`. | ||
@@ -76,3 +78,3 @@ `width` is the Number of pixels wide the resultant image should be. | ||
```javascript | ||
sharp.resize("input.jpg", sharp.buffer.png, 300, 200, {sharpen: true}, function(err, buffer) { | ||
sharp.resize("input.webp", sharp.buffer.png, 300, 200, {sharpen: true}, function(err, buffer) { | ||
if (err) { | ||
@@ -86,7 +88,7 @@ throw err; | ||
```javascript | ||
sharp.resize(buffer, "output.jpg", 200, 300, {canvas: sharp.canvas.embedWhite}, function(err) { | ||
sharp.resize(buffer, "output.tiff", 200, 300, {canvas: sharp.canvas.embedWhite}, function(err) { | ||
if (err) { | ||
throw err; | ||
} | ||
// output.jpg is a 200 pixels wide and 300 pixels high image containing a scaled version | ||
// output.tiff is a 200 pixels wide and 300 pixels high image containing a scaled version | ||
// of the image data contained in buffer embedded on a white canvas | ||
@@ -97,7 +99,7 @@ }); | ||
```javascript | ||
sharp.resize("input.jpg", sharp.buffer.jpeg, 200, 300, {canvas: sharp.canvas.embedBlack}, function(err, buffer) { | ||
sharp.resize("input.jpg", sharp.buffer.webp, 200, 300, {canvas: sharp.canvas.embedBlack}, function(err, buffer) { | ||
if (err) { | ||
throw err; | ||
} | ||
// buffer contains JPEG image data of a 200 pixels wide and 300 pixels high image | ||
// buffer contains WebP image data of a 200 pixels wide and 300 pixels high image | ||
// containing a scaled version of input.png embedded on a black canvas | ||
@@ -116,6 +118,8 @@ }); | ||
* AMD Athlon 4 core 3.3GHz 512KB L2 CPU 1333 DDR3 | ||
* libvips 7.37 | ||
* libvips 7.38 | ||
* libjpeg-turbo8 1.3.0 | ||
* libpng 1.6.6 | ||
* zlib1g 1.2.7 | ||
* libwebp 0.3.0 | ||
* libtiff 4.0.2 | ||
@@ -158,2 +162,17 @@ `-file-buffer` indicates read from file and write to buffer, `-buffer-file` indicates read from buffer and write to file etc. | ||
### WebP | ||
* sharp-buffer-file x 3.30 ops/sec ±117.14% (19 runs sampled) | ||
* sharp-buffer-buffer x 7.66 ops/sec ±5.83% (43 runs sampled) | ||
* sharp-file-file x 9.88 ops/sec ±0.98% (52 runs sampled) | ||
* sharp-file-buffer x 9.95 ops/sec ±0.25% (52 runs sampled) | ||
* sharp-file-buffer-sharpen x 9.05 ops/sec ±0.36% (48 runs sampled) | ||
* sharp-file-buffer-sequentialRead x 9.87 ops/sec ±0.98% (52 runs sampled) | ||
### TIFF | ||
* sharp-file-file x 68.24 ops/sec ±5.93% (85 runs sampled) | ||
* sharp-file-file-sharpen x 50.76 ops/sec ±0.52% (82 runs sampled) | ||
* sharp-file-file-sequentialRead x 36.37 ops/sec ±0.90% (87 runs sampled) | ||
## Licence | ||
@@ -160,0 +179,0 @@ |
@@ -16,2 +16,8 @@ var sharp = require("../index"); | ||
var inputWebp = __dirname + "/4.webp"; // http://www.gstatic.com/webp/gallery/4.webp | ||
var outputWebp = __dirname + "/output.webp"; | ||
var inputTiff = __dirname + "/G31D.TIF"; // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm | ||
var outputTiff = __dirname + "/output.tiff"; | ||
var width = 720; | ||
@@ -294,3 +300,121 @@ var height = 480; | ||
}).run(); | ||
} | ||
}, | ||
webp: function(callback) { | ||
var inputWebpBuffer = fs.readFileSync(inputWebp); | ||
(new Benchmark.Suite("webp")).add("sharp-buffer-file", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputWebpBuffer, outputWebp, width, height, function(err) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-buffer-buffer", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputWebpBuffer, sharp.buffer.webp, width, height, function(err, buffer) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
assert.notStrictEqual(null, buffer); | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-file-file", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputWebp, outputWebp, width, height, function(err) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-file-buffer", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputWebp, sharp.buffer.webp, width, height, function(err, buffer) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
assert.notStrictEqual(null, buffer); | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-file-buffer-sharpen", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputWebp, sharp.buffer.webp, width, height, {sharpen: true}, function(err, buffer) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
assert.notStrictEqual(null, buffer); | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-file-buffer-sequentialRead", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputWebp, sharp.buffer.webp, width, height, {sequentialRead: true}, function(err, buffer) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
assert.notStrictEqual(null, buffer); | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).on("cycle", function(event) { | ||
console.log("webp " + String(event.target)); | ||
}).on("complete", function() { | ||
callback(null, this.filter("fastest").pluck("name")); | ||
}).run(); | ||
}, | ||
tiff: function(callback) { | ||
(new Benchmark.Suite("tiff")).add("sharp-file-file", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputTiff, outputTiff, width, height, function(err) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-file-file-sharpen", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputTiff, outputTiff, width, height, {sharpen: true}, function(err) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).add("sharp-file-file-sequentialRead", { | ||
defer: true, | ||
fn: function(deferred) { | ||
sharp.resize(inputTiff, outputTiff, width, height, {sequentialRead: true}, function(err) { | ||
if (err) { | ||
throw err; | ||
} else { | ||
deferred.resolve(); | ||
} | ||
}); | ||
} | ||
}).on("cycle", function(event) { | ||
console.log("tiff " + String(event.target)); | ||
}).on("complete", function() { | ||
callback(null, this.filter("fastest").pluck("name")); | ||
}).run(); | ||
} | ||
}, function(err, results) { | ||
@@ -297,0 +421,0 @@ assert(!err, err); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1268021
32.29%13
18.18%505
32.2%184
11.52%