Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sharp

Package Overview
Dependencies
Maintainers
1
Versions
156
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sharp - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

.travis.yml

27

package.json
{
"name": "sharp",
"version": "0.2.0",
"author": "Lovell Fuller",
"description": "High performance module to resize JPEG, PNG, WebP and TIFF images using the libvips image processing library",
"version": "0.3.0",
"author": "Lovell Fuller <npm@lovell.info>",
"contributors": [
"Pierre Inglebert <pierre.inglebert@gmail.com>"
],
"description": "High performance Node.js module to resize JPEG, PNG and WebP images using the libvips library",
"scripts": {

@@ -19,2 +22,3 @@ "test": "node tests/unit && node tests/perf"

"tiff",
"gif",
"resize",

@@ -30,13 +34,16 @@ "thumbnail",

],
"dependencies": {
"nan": "^0.8.0"
},
"devDependencies": {
"imagemagick": "*",
"gm": "*",
"epeg": "*",
"async": "*",
"benchmark": "*"
"imagemagick": "^0.1.3",
"imagemagick-native": "^0.2.9",
"gm": "^1.14.2",
"async": "^0.6.2",
"benchmark": "^1.0.0"
},
"license": "Apache 2.0",
"engines": {
"node": ">=0.8"
"node": ">=0.10"
}
}
}
# sharp
_adj_
* [Installation](https://github.com/lovell/sharp#installation)
* [Usage examples](https://github.com/lovell/sharp#usage-examples)
* [API](https://github.com/lovell/sharp#api)
* [Testing](https://github.com/lovell/sharp#testing)
* [Performance](https://github.com/lovell/sharp#performance)
* [Licence](https://github.com/lovell/sharp#licence)
1. clearly defined; distinct: a sharp photographic image.
2. quick, brisk, or spirited.
3. shrewd or astute: a sharp bargainer.
4. (Informal.) very stylish: a sharp dresser; a sharp jacket.
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 JPEG, PNG, WebP and TIFF images to smaller 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 15x-25x faster than ImageMagick and GraphicsMagick, based mainly on the number of CPU cores available.
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 to and from both the filesystem and Buffer objects (TIFF is limited to filesystem only). Everything remains non-blocking thanks to _libuv_.
When generating JPEG output all metadata is removed and Huffman tables optimised without having to use separate command line tools like [jpegoptim](https://github.com/tjko/jpegoptim) and [jpegtran](http://jpegclub.org/jpegtran/).
Anyone who has used the Node.js bindings for [GraphicsMagick](https://github.com/aheckmann/gm) will find the API similarly expressive.
Anyone who has used the Node.js bindings for [GraphicsMagick](https://github.com/aheckmann/gm) will find the API similarly fluent.
This module is powered by 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.
## Prerequisites
## Installation
* Node.js v0.8+
npm install sharp
### Prerequisites
* Node.js v0.10+
* [libvips](https://github.com/jcupitt/libvips) v7.38.5+

@@ -27,4 +33,8 @@

brew install homebrew/science/vips
brew install homebrew/science/vips --with-webp --with-graphicsmagick
The _gettext_ dependency of _libvips_ [can lead](https://github.com/lovell/sharp/issues/9) to a `library not found for -lintl` error. If so, please try:
brew link gettext --force
### Install libvips on Ubuntu/Debian Linux

@@ -35,4 +45,5 @@

cd libvips
git checkout 7.38
./bootstrap.sh
./configure --enable-debug=no
./configure --enable-debug=no --enable-cxx=no --without-python
make

@@ -42,5 +53,7 @@ sudo make install

## Install
Ubuntu 12.04 requires `libtiff4-dev` instead of `libtiff5-dev` and has [a bug](https://bugs.launchpad.net/ubuntu/+source/libwebp/+bug/1108731) in the libwebp package. Work around these problems by running these command first:
npm install sharp
sudo add-apt-repository ppa:lyrasis/precise-backports
sudo apt-get update
sudo apt-get install libtiff4-dev

@@ -92,3 +105,3 @@ ## Usage examples

```javascript
sharp('input.jpg').resize(200, 300).embedBlack().webp(function(err, buffer) {
sharp('input.gif').resize(200, 300).embedBlack().webp(function(err, buffer) {
if (err) {

@@ -98,3 +111,3 @@ throw err;

// buffer contains WebP image data of a 200 pixels wide and 300 pixels high image
// containing a scaled version, embedded on a black canvas, of input.png
// containing a scaled version, embedded on a black canvas, of input.gif
});

@@ -107,5 +120,6 @@ ```

Constructor to which further methods are chained.
Constructor to which further methods are chained. `input` can be one of:
`input` can either be a filename String or a Buffer.
* Buffer containing JPEG, PNG or WebP image data, or
* String containing the filename of an image, with most major formats supported.

@@ -138,3 +152,3 @@ ### resize(width, [height])

Use progressive (interlace) scan for the output. This typically reduces performance by 30%.
Use progressive (interlace) scan for JPEG and PNG output. This typically reduces compression performance by 30% but results in an image that can be rendered sooner when decompressed.

@@ -171,3 +185,3 @@ ### sequentialRead()

Write image data to a Buffer, the format of which will match the input image.
Write image data to a Buffer, the format of which will match the input image. JPEG, PNG and WebP are supported.

@@ -192,70 +206,55 @@ `callback` gets two arguments `(err, buffer)` where `err` is an error message, if any, and `buffer` is the resultant image data.

[![Build Status](https://travis-ci.org/lovell/sharp.png?branch=master)](https://travis-ci.org/lovell/sharp)
npm test
## Performance
Running the tests requires both ImageMagick and GraphicsMagick plus one of either libmagick++-dev or libgraphicsmagick++.
Test environment:
brew install imagemagick
brew install graphicsmagick
* AMD Athlon 4 core 3.3GHz 512KB L2 CPU 1333 DDR3
* libvips 7.38
* libjpeg-turbo8 1.3.0
* libpng 1.6.6
* zlib1g 1.2.7
* libwebp 0.3.0
* libtiff 4.0.2
sudo apt-get install imagemagick graphicsmagick libmagick++-dev
`-file-buffer` indicates read from file and write to buffer, `-buffer-file` indicates read from buffer and write to file etc.
## Performance
`-sharpen`, `-progressive` etc. demonstrate the negative effect of options on performance.
### Test environment
### JPEG
* Intel Xeon [L5520](http://ark.intel.com/products/40201/Intel-Xeon-Processor-L5520-8M-Cache-2_26-GHz-5_86-GTs-Intel-QPI) 2.27GHz 8MB cache
* Ubuntu 13.10
* libvips 7.38.5
* imagemagick x 5.53 ops/sec ±0.62% (31 runs sampled)
* gm-file-file x 4.10 ops/sec ±0.41% (25 runs sampled)
* gm-file-buffer x 4.10 ops/sec ±0.36% (25 runs sampled)
* epeg-file-file x 23.82 ops/sec ±0.18% (60 runs sampled)
* epeg-file-buffer x 23.98 ops/sec ±0.16% (61 runs sampled)
### The contenders
* sharp-buffer-file x 20.76 ops/sec ±0.55% (54 runs sampled)
* sharp-buffer-buffer x 20.90 ops/sec ±0.26% (54 runs sampled)
* sharp-file-file x 91.78 ops/sec ±0.38% (88 runs sampled)
* sharp-file-buffer x __93.05 ops/sec__ ±0.61% (76 runs sampled)
* [imagemagick-native](https://github.com/mash/node-imagemagick-native) - Supports Buffers only and blocks main V8 thread whilst processing.
* [imagemagick](https://github.com/rsms/node-imagemagick) - Supports filesystem only and "has been unmaintained for a long time".
* [gm](https://github.com/aheckmann/gm) - Fully featured wrapper around GraphicsMagick.
* sharp - Caching within libvips disabled to ensure a fair comparison.
* sharp-file-buffer-sharpen x 63.09 ops/sec ±5.58% (63 runs sampled)
* sharp-file-buffer-progressive x 61.68 ops/sec ±0.53% (76 runs sampled)
* sharp-file-buffer-sequentialRead x 60.66 ops/sec ±0.38% (75 runs sampled)
### The task
### PNG
Decompress a 2725x2225 JPEG image, resize and crop to 720x480, then compress to JPEG.
* imagemagick x 4.27 ops/sec ±0.21% (25 runs sampled)
* gm-file-file x 8.33 ops/sec ±0.19% (44 runs sampled)
* gm-file-buffer x 7.45 ops/sec ±0.16% (40 runs sampled)
* sharp-buffer-file x 4.94 ops/sec ±118.46% (26 runs sampled)
* sharp-buffer-buffer x 12.59 ops/sec ±0.55% (64 runs sampled)
* sharp-file-file x 44.06 ops/sec ±6.86% (75 runs sampled)
* sharp-file-buffer x __46.29 ops/sec__ ±0.38% (76 runs sampled)
### Results
* sharp-file-buffer-sharpen x 38.86 ops/sec ±0.22% (65 runs sampled)
* sharp-file-buffer-progressive x 46.35 ops/sec ±0.20% (76 runs sampled)
* sharp-file-buffer-sequentialRead x 29.02 ops/sec ±0.62% (72 runs sampled)
| Module | Input | Output | Ops/sec | Speed-up |
| :-------------------- | :----- | :----- | ------: | -------: |
| imagemagick-native | buffer | buffer | 0.97 | 1 |
| imagemagick | file | file | 2.49 | 2.6 |
| gm | buffer | file | 3.72 | 3.8 |
| gm | buffer | buffer | 3.80 | 3.9 |
| gm | file | file | 3.67 | 3.8 |
| gm | file | buffer | 3.67 | 3.8 |
| sharp | buffer | file | 13.62 | 14.0 |
| sharp | buffer | buffer | 12.43 | 12.8 |
| sharp | file | file | 13.02 | 13.4 |
| sharp | file | buffer | 11.15 | 11.5 |
| sharp +sharpen | file | buffer | 10.26 | 10.6 |
| sharp +progressive | file | buffer | 9.44 | 9.7 |
| sharp +sequentialRead | file | buffer | 11.94 | 12.3 |
### WebP
You can expect much greater performance with caching enabled (default) and using 16+ core machines.
* 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
Copyright 2013, 2014 Lovell Fuller
Copyright 2013, 2014 Lovell Fuller and Pierre Inglebert

@@ -262,0 +261,0 @@ Licensed under the Apache License, Version 2.0 (the "License");

var sharp = require("../index");
var fs = require("fs");
var path = require("path");
var assert = require("assert");
var async = require("async");
var inputJpg = __dirname + "/2569067123_aca715a2ee_o.jpg"; // http://www.flickr.com/photos/grizdave/2569067123/
var inputJpg = path.join(__dirname, "fixtures/2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/
var width = 720;

@@ -8,0 +9,0 @@ var height = 480;

var sharp = require("../index");
var fs = require("fs");
var path = require("path");
var imagemagick = require("imagemagick");
var imagemagickNative = require("imagemagick-native");
var gm = require("gm");
var epeg = require("epeg");
var async = require("async");

@@ -10,21 +11,28 @@ var assert = require("assert");

var inputJpg = __dirname + "/2569067123_aca715a2ee_o.jpg"; // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = __dirname + "/output.jpg";
var fixturesPath = path.join(__dirname, "fixtures");
var inputPng = __dirname + "/50020484-00001.png"; // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
var outputPng = __dirname + "/output.png";
var inputJpg = path.join(fixturesPath, "2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = path.join(fixturesPath, "output.jpg");
var inputWebp = __dirname + "/4.webp"; // http://www.gstatic.com/webp/gallery/4.webp
var outputWebp = __dirname + "/output.webp";
var inputPng = path.join(fixturesPath, "50020484-00001.png"); // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
var outputPng = path.join(fixturesPath, "output.png");
var inputTiff = __dirname + "/G31D.TIF"; // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
var outputTiff = __dirname + "/output.tiff";
var inputWebp = path.join(fixturesPath, "4.webp"); // http://www.gstatic.com/webp/gallery/4.webp
var outputWebp = path.join(fixturesPath, "output.webp");
var inputTiff = path.join(fixturesPath, "G31D.TIF"); // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
var outputTiff = path.join(fixturesPath, "output.tiff");
var inputGif = path.join(fixturesPath, "Crash_test.gif"); // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif
var width = 720;
var height = 480;
// Disable libvips cache to ensure tests are as fair as they can be
sharp.cache(0);
async.series({
jpeg: function(callback) {
var inputJpgBuffer = fs.readFileSync(inputJpg);
(new Benchmark.Suite("jpeg")).add("imagemagick", {
(new Benchmark.Suite("jpeg")).add("imagemagick-file-file", {
defer: true,

@@ -46,6 +54,18 @@ fn: function(deferred) {

}
}).add("gm-file-file", {
}).add("imagemagick-native-buffer-buffer", {
defer: true,
fn: function(deferred) {
gm(inputJpg).resize(width, height).quality(80).write(outputJpg, function (err) {
imagemagickNative.convert({
srcData: inputJpgBuffer,
quality: 80,
width: width,
height: height,
format: 'JPEG'
});
deferred.resolve();
}
}).add("gm-buffer-file", {
defer: true,
fn: function(deferred) {
gm(inputJpgBuffer).resize(width, height).quality(80).write(outputJpg, function (err) {
if (err) {

@@ -58,6 +78,6 @@ throw err;

}
}).add("gm-file-buffer", {
}).add("gm-buffer-buffer", {
defer: true,
fn: function(deferred) {
gm(inputJpg).resize(width, height).quality(80).toBuffer(function (err, buffer) {
gm(inputJpgBuffer).resize(width, height).quality(80).toBuffer(function (err, buffer) {
if (err) {

@@ -71,16 +91,24 @@ throw err;

}
}).add("epeg-file-file", {
}).add("gm-file-file", {
defer: true,
fn: function(deferred) {
var image = new epeg.Image({path: inputJpg});
image.downsize(width, height, 80).saveTo(outputJpg);
deferred.resolve();
gm(inputJpg).resize(width, height).quality(80).write(outputJpg, function (err) {
if (err) {
throw err;
} else {
deferred.resolve();
}
});
}
}).add("epeg-file-buffer", {
}).add("gm-file-buffer", {
defer: true,
fn: function(deferred) {
var image = new epeg.Image({path: inputJpg});
var buffer = image.downsize(width, height, 80).process();
assert.notStrictEqual(null, buffer);
deferred.resolve();
gm(inputJpg).resize(width, height).quality(80).toBuffer(function (err, buffer) {
if (err) {
throw err;
} else {
assert.notStrictEqual(null, buffer);
deferred.resolve();
}
});
}

@@ -177,3 +205,3 @@ }).add("sharp-buffer-file", {

var inputPngBuffer = fs.readFileSync(inputPng);
(new Benchmark.Suite("png")).add("imagemagick", {
(new Benchmark.Suite("png")).add("imagemagick-file-file", {
defer: true,

@@ -194,2 +222,13 @@ fn: function(deferred) {

}
}).add("imagemagick-native-buffer-buffer", {
defer: true,
fn: function(deferred) {
imagemagickNative.convert({
srcData: inputPngBuffer,
width: width,
height: height,
format: 'PNG'
});
deferred.resolve();
}
}).add("gm-file-file", {

@@ -423,2 +462,42 @@ defer: true,

}).run();
},
gif: function(callback) {
(new Benchmark.Suite("gif")).add("sharp-file-file", {
defer: true,
fn: function(deferred) {
sharp(inputGif).resize(width, height).write(outputTiff, function(err) {
if (err) {
throw err;
} else {
deferred.resolve();
}
});
}
}).add("sharp-file-file-sharpen", {
defer: true,
fn: function(deferred) {
sharp(inputGif).resize(width, height).sharpen().write(outputTiff, function(err) {
if (err) {
throw err;
} else {
deferred.resolve();
}
});
}
}).add("sharp-file-file-sequentialRead", {
defer: true,
fn: function(deferred) {
sharp(inputGif).sequentialRead().resize(width, height).write(outputTiff, function(err) {
if (err) {
throw err;
} else {
deferred.resolve();
}
});
}
}).on("cycle", function(event) {
console.log("gif " + String(event.target));
}).on("complete", function() {
callback(null, this.filter("fastest").pluck("name"));
}).run();
}

@@ -428,5 +507,7 @@ }, function(err, results) {

Object.keys(results).forEach(function(format) {
assert.strictEqual("sharp", results[format].toString().substr(0, 5), "sharp was slower than " + results[format] + " for " + format);
if (results[format].toString().substr(0, 5) !== "sharp") {
console.log("sharp was slower than " + results[format] + " for " + format);
}
});
console.dir(sharp.cache());
});
var sharp = require("../index");
var fs = require("fs");
var path = require("path");
var imagemagick = require("imagemagick");
var gm = require("gm");
var epeg = require("epeg");
var async = require("async");

@@ -10,4 +10,5 @@ var assert = require("assert");

var inputJpg = __dirname + "/2569067123_aca715a2ee_o.jpg"; // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = __dirname + "/output.jpg";
var fixturesPath = path.join(__dirname, "fixtures");
var inputJpg = path.join(fixturesPath, "2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = path.join(fixturesPath, "output.jpg");

@@ -50,10 +51,2 @@ var min = 320;

}
}).add("epeg", {
defer: true,
fn: function(deferred) {
var image = new epeg.Image({path: inputJpg});
var buffer = image.downsize(randomDimension(), randomDimension(), 80).process();
assert.notStrictEqual(null, buffer);
deferred.resolve();
}
}).add("sharp", {

@@ -60,0 +53,0 @@ defer: true,

var sharp = require("../index");
var path = require("path");
var imagemagick = require("imagemagick");

@@ -6,5 +7,7 @@ var assert = require("assert");

var inputJpg = __dirname + "/2569067123_aca715a2ee_o.jpg"; // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = __dirname + "/output.jpg";
var fixturesPath = path.join(__dirname, "fixtures");
var inputJpg = path.join(fixturesPath, "2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/
var outputJpg = path.join(fixturesPath, "output.jpg");
async.series([

@@ -11,0 +14,0 @@ // Resize with exact crop

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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