mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 13:46:19 +01:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18fd6ef119 | ||
|
|
0004f5d2ff | ||
|
|
5f29d1ba9c | ||
|
|
791fd35c35 | ||
|
|
e0d622d347 | ||
|
|
6b34e8a804 | ||
|
|
eb8773fe3e | ||
|
|
b40e3fa1f1 | ||
|
|
d25d761b55 | ||
|
|
d6051dd714 | ||
|
|
53ff061efa | ||
|
|
72b0efd393 | ||
|
|
df97ef23d9 | ||
|
|
f6373971bd | ||
|
|
ec617f2489 | ||
|
|
502ae78579 | ||
|
|
49297d6afb | ||
|
|
29354badd8 | ||
|
|
3c4de796c8 | ||
|
|
c7f4488e77 | ||
|
|
d8765f955d |
@@ -30,8 +30,11 @@ import sharp from 'sharp';
|
|||||||
sharp(inputBuffer)
|
sharp(inputBuffer)
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.toFile('output.webp', (err, info) => ... );
|
.toFile('output.webp', (err, info) => ... );
|
||||||
|
// A Promises/A+ promise is returned when callback is not provided.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
sharp('input.jpg')
|
sharp('input.jpg')
|
||||||
.rotate()
|
.rotate()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
}],
|
}],
|
||||||
['OS == "linux"', {
|
['OS == "linux"', {
|
||||||
'variables': {
|
'variables': {
|
||||||
'download_vips': '<!(LDD_VERSION="<!(ldd --version 2>&1 || true)" node -e "require(\'./binding\').download_vips()")'
|
'download_vips': '<!(node -e "require(\'./binding\').download_vips()")'
|
||||||
},
|
},
|
||||||
'defines': [
|
'defines': [
|
||||||
'_GLIBCXX_USE_CXX11_ABI=0'
|
'_GLIBCXX_USE_CXX11_ABI=0'
|
||||||
|
|||||||
40
binding.js
40
binding.js
@@ -5,11 +5,12 @@ const os = require('os');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const caw = require('caw');
|
const caw = require('caw');
|
||||||
const got = require('got');
|
const simpleGet = require('simple-get');
|
||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
const tar = require('tar');
|
const tar = require('tar');
|
||||||
|
const detectLibc = require('detect-libc');
|
||||||
|
|
||||||
const distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';
|
const distBaseUrl = process.env.SHARP_DIST_BASE_URL || 'https://dl.bintray.com/lovell/sharp/';
|
||||||
|
|
||||||
// Use NPM-provided environment variable where available, falling back to require-based method for Electron
|
// Use NPM-provided environment variable where available, falling back to require-based method for Electron
|
||||||
const minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;
|
const minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;
|
||||||
@@ -68,19 +69,15 @@ module.exports.download_vips = function () {
|
|||||||
if (!isFile(vipsHeaderPath)) {
|
if (!isFile(vipsHeaderPath)) {
|
||||||
// Ensure Intel 64-bit or ARM
|
// Ensure Intel 64-bit or ARM
|
||||||
if (arch === 'ia32') {
|
if (arch === 'ia32') {
|
||||||
error('Intel Architecture 32-bit systems require manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
error('Intel Architecture 32-bit systems require manual installation of libvips - please see http://sharp.dimens.io/page/install');
|
||||||
}
|
}
|
||||||
// Ensure glibc >= 2.15
|
// Ensure glibc Linux
|
||||||
const lddVersion = process.env.LDD_VERSION;
|
if (detectLibc.isNonGlibcLinux) {
|
||||||
if (lddVersion) {
|
error(`Use with ${detectLibc.family} libc requires manual installation of libvips - please see http://sharp.dimens.io/page/install`);
|
||||||
if (/(glibc|gnu libc|gentoo)/i.test(lddVersion)) {
|
}
|
||||||
const glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
|
// Ensure glibc >= 2.13
|
||||||
if (glibcVersion && semver.lt(glibcVersion + '.0', '2.13.0')) {
|
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.13.0')) {
|
||||||
error('glibc version ' + glibcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips - please see http://sharp.dimens.io/page/install`);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error(lddVersion.split(/\n/)[0] + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Arch/platform-specific .tar.gz
|
// Arch/platform-specific .tar.gz
|
||||||
const tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
|
const tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
|
||||||
@@ -98,19 +95,22 @@ module.exports.download_vips = function () {
|
|||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const gotOpt = {
|
const url = distBaseUrl + tarFilename;
|
||||||
|
const simpleGetOpt = {
|
||||||
|
url: url,
|
||||||
agent: caw(null, {
|
agent: caw(null, {
|
||||||
protocol: 'https'
|
protocol: 'https'
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
const url = distBaseUrl + tarFilename;
|
simpleGet(simpleGetOpt, function (err, response) {
|
||||||
got.stream(url, gotOpt).on('response', function (response) {
|
if (err) {
|
||||||
|
error('Download of ' + url + ' failed: ' + err.message);
|
||||||
|
}
|
||||||
if (response.statusCode !== 200) {
|
if (response.statusCode !== 200) {
|
||||||
error(url + ' status code ' + response.statusCode);
|
error(url + ' status code ' + response.statusCode);
|
||||||
}
|
}
|
||||||
}).on('error', function (err) {
|
response.pipe(tmpFile);
|
||||||
error('Download of ' + url + ' failed: ' + err.message);
|
});
|
||||||
}).pipe(tmpFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
machine:
|
machine:
|
||||||
node:
|
node:
|
||||||
version: v4.6.1
|
version: v4.8.4
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
test:
|
test:
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ Use these TIFF options for output image.
|
|||||||
- `options.force` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** force TIFF output, otherwise attempt to use input format (optional, default `true`)
|
- `options.force` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** force TIFF output, otherwise attempt to use input format (optional, default `true`)
|
||||||
- `options.compression` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** compression options: lzw, deflate, jpeg (optional, default `'jpeg'`)
|
- `options.compression` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** compression options: lzw, deflate, jpeg (optional, default `'jpeg'`)
|
||||||
- `options.predictor` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** compression predictor options: none, horizontal, float (optional, default `'none'`)
|
- `options.predictor` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** compression predictor options: none, horizontal, float (optional, default `'none'`)
|
||||||
|
- `options.xres` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** horizontal resolution in pixels/mm (optional, default `1.0`)
|
||||||
|
- `options.yres` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** vertical resolution in pixels/mm (optional, default `1.0`)
|
||||||
- `options.squash` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** squash 8-bit images down to 1 bit (optional, default `false`)
|
- `options.squash` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** squash 8-bit images down to 1 bit (optional, default `false`)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
|
|
||||||
## cache
|
## cache
|
||||||
|
|
||||||
Gets, or when options are provided sets, the limits of _libvips'_ operation cache.
|
Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
|
||||||
Existing entries in the cache will be trimmed after any change in limits.
|
Existing entries in the cache will be trimmed after any change in limits.
|
||||||
This method always returns cache statistics,
|
This method always returns cache statistics,
|
||||||
useful for determining how much working memory is required for a particular task.
|
useful for determining how much working memory is required for a particular task.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `options` **([Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** Object with the following attributes, or Boolean where true uses default cache settings and false removes all caching.
|
- `options` **([Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** Object with the following attributes, or Boolean where true uses default cache settings and false removes all caching (optional, default `true`)
|
||||||
- `options.memory` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** is the maximum memory in MB to use for this cache (optional, default `50`)
|
- `options.memory` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** is the maximum memory in MB to use for this cache (optional, default `50`)
|
||||||
- `options.files` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** is the maximum number of files to hold open (optional, default `20`)
|
- `options.files` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** is the maximum number of files to hold open (optional, default `20`)
|
||||||
- `options.items` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** is the maximum number of operations to cache (optional, default `100`)
|
- `options.items` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** is the maximum number of operations to cache (optional, default `100`)
|
||||||
@@ -37,7 +37,7 @@ Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer
|
|||||||
|
|
||||||
## concurrency
|
## concurrency
|
||||||
|
|
||||||
Gets, or when a concurrency is provided sets,
|
Gets or, when a concurrency is provided, sets
|
||||||
the number of threads _libvips'_ should create to process each image.
|
the number of threads _libvips'_ should create to process each image.
|
||||||
The default value is the number of CPU cores.
|
The default value is the number of CPU cores.
|
||||||
A value of `0` will reset to this default.
|
A value of `0` will reset to this default.
|
||||||
|
|||||||
@@ -4,6 +4,33 @@
|
|||||||
|
|
||||||
Requires libvips v8.5.5.
|
Requires libvips v8.5.5.
|
||||||
|
|
||||||
|
#### v0.18.3 - 13<sup>th</sup> September 2017
|
||||||
|
|
||||||
|
* Skip shrink-on-load when trimming.
|
||||||
|
[#888](https://github.com/lovell/sharp/pull/888)
|
||||||
|
[@kleisauke](https://github.com/kleisauke)
|
||||||
|
|
||||||
|
* Migrate from got to simple-get for basic auth support.
|
||||||
|
[#945](https://github.com/lovell/sharp/pull/945)
|
||||||
|
[@pbomb](https://github.com/pbomb)
|
||||||
|
|
||||||
|
#### v0.18.2 - 1<sup>st</sup> July 2017
|
||||||
|
|
||||||
|
* Expose libvips' xres and yres properties for TIFF output.
|
||||||
|
[#828](https://github.com/lovell/sharp/pull/828)
|
||||||
|
[@YvesBos](https://github.com/YvesBos)
|
||||||
|
|
||||||
|
* Ensure flip and flop operations work with auto-rotate.
|
||||||
|
[#837](https://github.com/lovell/sharp/issues/837)
|
||||||
|
[@rexxars](https://github.com/rexxars)
|
||||||
|
|
||||||
|
* Allow binary download URL override via SHARP_DIST_BASE_URL env variable.
|
||||||
|
[#841](https://github.com/lovell/sharp/issues/841)
|
||||||
|
|
||||||
|
* Add support for Solus Linux.
|
||||||
|
[#857](https://github.com/lovell/sharp/pull/857)
|
||||||
|
[@ekremkaraca](https://github.com/ekremkaraca)
|
||||||
|
|
||||||
#### v0.18.1 - 30<sup>th</sup> May 2017
|
#### v0.18.1 - 30<sup>th</sup> May 2017
|
||||||
|
|
||||||
* Remove regression from #781 that could cause incorrect shrink calculation.
|
* Remove regression from #781 that could cause incorrect shrink calculation.
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ the help and code contributions of the following people:
|
|||||||
* [Alice Monday](https://github.com/alice0meta)
|
* [Alice Monday](https://github.com/alice0meta)
|
||||||
* [Kristo Jorgenson](https://github.com/kristojorg)
|
* [Kristo Jorgenson](https://github.com/kristojorg)
|
||||||
* [Yves Bos](https://github.com/YvesBos)
|
* [Yves Bos](https://github.com/YvesBos)
|
||||||
|
* [Nicolas Coden](https://github.com/ncoden)
|
||||||
|
* [Matt Parrish](https://github.com/pbomb)
|
||||||
|
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ yarn add sharp
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
* Node v4+
|
* Node v4.5.0+
|
||||||
* C++11 compatible compiler such as gcc 4.8+, clang 3.0+ or MSVC 2013+
|
* C++11 compatible compiler such as gcc 4.8+, clang 3.0+ or MSVC 2013+
|
||||||
* [node-gyp](https://github.com/TooTallNate/node-gyp#installation) and its dependencies (includes Python)
|
* [node-gyp](https://github.com/TooTallNate/node-gyp#installation) and its dependencies (includes Python)
|
||||||
|
|
||||||
@@ -32,6 +32,7 @@ Most recent Linux-based operating systems with glibc running on x64 and ARMv6+ C
|
|||||||
* Archlinux
|
* Archlinux
|
||||||
* Raspbian Jessie
|
* Raspbian Jessie
|
||||||
* Amazon Linux 2016.03, 2016.09
|
* Amazon Linux 2016.03, 2016.09
|
||||||
|
* Solus
|
||||||
|
|
||||||
To use a globally-installed version of libvips instead of the provided binaries,
|
To use a globally-installed version of libvips instead of the provided binaries,
|
||||||
make sure it is at least the version listed under `config.libvips` in the `package.json` file
|
make sure it is at least the version listed under `config.libvips` in the `package.json` file
|
||||||
@@ -46,10 +47,19 @@ This allows the use of newer versions of libvips with older versions of sharp.
|
|||||||
For 32-bit Intel CPUs and older Linux-based operating systems such as Centos 6,
|
For 32-bit Intel CPUs and older Linux-based operating systems such as Centos 6,
|
||||||
it is recommended to install a system-wide installation of libvips from source:
|
it is recommended to install a system-wide installation of libvips from source:
|
||||||
|
|
||||||
https://github.com/jcupitt/libvips#building-libvips-from-a-source-tarball
|
https://jcupitt.github.io/libvips/install.html#building-libvips-from-a-source-tarball
|
||||||
|
|
||||||
For Linux-based operating systems such as Alpine that use musl libc,
|
#### Alpine Linux
|
||||||
the smaller stack size means libvips' cache should be disabled
|
|
||||||
|
libvips is available in the
|
||||||
|
[testing repository](https://pkgs.alpinelinux.org/packages?name=vips-dev):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
apk add vips-dev fftw-dev --update-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/
|
||||||
|
```
|
||||||
|
|
||||||
|
The smaller stack size of musl libc means
|
||||||
|
libvips may need to be used without a cache
|
||||||
via `sharp.cache(false)` to avoid a stack overflow.
|
via `sharp.cache(false)` to avoid a stack overflow.
|
||||||
|
|
||||||
### Mac OS
|
### Mac OS
|
||||||
@@ -81,6 +91,9 @@ This can be achieved via [FreshPorts](https://www.freshports.org/graphics/vips/)
|
|||||||
cd /usr/ports/graphics/vips/ && make install clean
|
cd /usr/ports/graphics/vips/ && make install clean
|
||||||
```
|
```
|
||||||
|
|
||||||
|
FreeBSD's gcc v4 and v5 need `CXXFLAGS=-D_GLIBCXX_USE_C99` set for C++11 support due to
|
||||||
|
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193528
|
||||||
|
|
||||||
### Heroku
|
### Heroku
|
||||||
|
|
||||||
libvips and its dependencies are fetched and stored within `node_modules\sharp\vendor` during `npm install`.
|
libvips and its dependencies are fetched and stored within `node_modules\sharp\vendor` during `npm install`.
|
||||||
@@ -183,16 +196,27 @@ configuration file to prevent the use of coders known to be vulnerable.
|
|||||||
Set the `MAGICK_CONFIGURE_PATH` environment variable
|
Set the `MAGICK_CONFIGURE_PATH` environment variable
|
||||||
to the directory containing the `policy.xml` file.
|
to the directory containing the `policy.xml` file.
|
||||||
|
|
||||||
### Licences
|
### Pre-compiled libvips binaries
|
||||||
|
|
||||||
If a global installation of libvips that meets the
|
If a global installation of libvips that meets the
|
||||||
minimum version requirement cannot be found,
|
minimum version requirement cannot be found,
|
||||||
this module will download a pre-compiled bundle of libvips
|
this module will attempt to download a pre-compiled bundle of libvips
|
||||||
and its dependencies on Linux and Windows machines.
|
and its dependencies on Linux and Windows machines.
|
||||||
|
|
||||||
Should you need to manually download and inspect these files,
|
Should you need to manually download and inspect these files,
|
||||||
you can do so via https://dl.bintray.com/lovell/sharp/
|
you can do so via https://dl.bintray.com/lovell/sharp/
|
||||||
|
|
||||||
|
Should you wish to install these from your own location,
|
||||||
|
set the `SHARP_DIST_BASE_URL` environment variable, e.g.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
SHARP_DIST_BASE_URL="https://hostname/path/" npm install sharp
|
||||||
|
```
|
||||||
|
|
||||||
|
to use `https://hostname/path/libvips-x.y.z-platform.tar.gz`.
|
||||||
|
|
||||||
|
### Licences
|
||||||
|
|
||||||
This module is licensed under the terms of the
|
This module is licensed under the terms of the
|
||||||
[Apache 2.0 Licence](https://github.com/lovell/sharp/blob/master/LICENSE).
|
[Apache 2.0 Licence](https://github.com/lovell/sharp/blob/master/LICENSE).
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ const Sharp = function (input, options) {
|
|||||||
tiffCompression: 'jpeg',
|
tiffCompression: 'jpeg',
|
||||||
tiffPredictor: 'none',
|
tiffPredictor: 'none',
|
||||||
tiffSquash: false,
|
tiffSquash: false,
|
||||||
|
tiffXres: 1.0,
|
||||||
|
tiffYres: 1.0,
|
||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
tileOverlap: 0,
|
tileOverlap: 0,
|
||||||
// Function to notify of libvips warnings
|
// Function to notify of libvips warnings
|
||||||
|
|||||||
@@ -214,6 +214,8 @@ function webp (options) {
|
|||||||
* @param {Boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
|
* @param {Boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
|
||||||
* @param {Boolean} [options.compression='jpeg'] - compression options: lzw, deflate, jpeg
|
* @param {Boolean} [options.compression='jpeg'] - compression options: lzw, deflate, jpeg
|
||||||
* @param {Boolean} [options.predictor='none'] - compression predictor options: none, horizontal, float
|
* @param {Boolean} [options.predictor='none'] - compression predictor options: none, horizontal, float
|
||||||
|
* @param {Number} [options.xres=1.0] - horizontal resolution in pixels/mm
|
||||||
|
* @param {Number} [options.yres=1.0] - vertical resolution in pixels/mm
|
||||||
* @param {Boolean} [options.squash=false] - squash 8-bit images down to 1 bit
|
* @param {Boolean} [options.squash=false] - squash 8-bit images down to 1 bit
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
@@ -233,6 +235,21 @@ function tiff (options) {
|
|||||||
throw new Error('Invalid Value for squash ' + options.squash + ' Only Boolean Values allowed for options.squash.');
|
throw new Error('Invalid Value for squash ' + options.squash + ' Only Boolean Values allowed for options.squash.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// resolution
|
||||||
|
if (is.object(options) && is.defined(options.xres)) {
|
||||||
|
if (is.number(options.xres)) {
|
||||||
|
this.options.tiffXres = options.xres;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid Value for xres ' + options.xres + ' Only numeric values allowed for options.xres');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is.object(options) && is.defined(options.yres)) {
|
||||||
|
if (is.number(options.yres)) {
|
||||||
|
this.options.tiffYres = options.yres;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid Value for yres ' + options.yres + ' Only numeric values allowed for options.yres');
|
||||||
|
}
|
||||||
|
}
|
||||||
// compression
|
// compression
|
||||||
if (is.defined(options) && is.defined(options.compression)) {
|
if (is.defined(options) && is.defined(options.compression)) {
|
||||||
if (is.string(options.compression) && is.inArray(options.compression, ['lzw', 'deflate', 'jpeg', 'none'])) {
|
if (is.string(options.compression) && is.inArray(options.compression, ['lzw', 'deflate', 'jpeg', 'none'])) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const is = require('./is');
|
|||||||
const sharp = require('../build/Release/sharp.node');
|
const sharp = require('../build/Release/sharp.node');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets, or when options are provided sets, the limits of _libvips'_ operation cache.
|
* Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
|
||||||
* Existing entries in the cache will be trimmed after any change in limits.
|
* Existing entries in the cache will be trimmed after any change in limits.
|
||||||
* This method always returns cache statistics,
|
* This method always returns cache statistics,
|
||||||
* useful for determining how much working memory is required for a particular task.
|
* useful for determining how much working memory is required for a particular task.
|
||||||
@@ -16,7 +16,7 @@ const sharp = require('../build/Release/sharp.node');
|
|||||||
* sharp.cache( { files: 0 } );
|
* sharp.cache( { files: 0 } );
|
||||||
* sharp.cache(false);
|
* sharp.cache(false);
|
||||||
*
|
*
|
||||||
* @param {Object|Boolean} options - Object with the following attributes, or Boolean where true uses default cache settings and false removes all caching.
|
* @param {Object|Boolean} [options=true] - Object with the following attributes, or Boolean where true uses default cache settings and false removes all caching
|
||||||
* @param {Number} [options.memory=50] - is the maximum memory in MB to use for this cache
|
* @param {Number} [options.memory=50] - is the maximum memory in MB to use for this cache
|
||||||
* @param {Number} [options.files=20] - is the maximum number of files to hold open
|
* @param {Number} [options.files=20] - is the maximum number of files to hold open
|
||||||
* @param {Number} [options.items=100] - is the maximum number of operations to cache
|
* @param {Number} [options.items=100] - is the maximum number of operations to cache
|
||||||
@@ -39,7 +39,7 @@ function cache (options) {
|
|||||||
cache(true);
|
cache(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets, or when a concurrency is provided sets,
|
* Gets or, when a concurrency is provided, sets
|
||||||
* the number of threads _libvips'_ should create to process each image.
|
* the number of threads _libvips'_ should create to process each image.
|
||||||
* The default value is the number of CPU cores.
|
* The default value is the number of CPU cores.
|
||||||
* A value of `0` will reset to this default.
|
* A value of `0` will reset to this default.
|
||||||
|
|||||||
18
package.json
18
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||||
"version": "0.18.1",
|
"version": "0.18.3",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://github.com/lovell/sharp",
|
"homepage": "https://github.com/lovell/sharp",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -37,7 +37,8 @@
|
|||||||
"Kristo Jorgenson <kristo.jorgenson@gmail.com>",
|
"Kristo Jorgenson <kristo.jorgenson@gmail.com>",
|
||||||
"YvesBos <yves_bos@outlook.com>",
|
"YvesBos <yves_bos@outlook.com>",
|
||||||
"Guy Maliar <guy@tailorbrands.com>",
|
"Guy Maliar <guy@tailorbrands.com>",
|
||||||
"Nicolas Coden <nicolas@ncoden.fr>"
|
"Nicolas Coden <nicolas@ncoden.fr>",
|
||||||
|
"Matt Parrish <matt.r.parrish@gmail.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf node_modules/ build/ vendor/ coverage/ test/fixtures/output.*",
|
"clean": "rm -rf node_modules/ build/ vendor/ coverage/ test/fixtures/output.*",
|
||||||
@@ -68,20 +69,21 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caw": "^2.0.0",
|
"caw": "^2.0.0",
|
||||||
"color": "^1.0.3",
|
"color": "^2.0.0",
|
||||||
"got": "^7.0.0",
|
"detect-libc": "^0.2.0",
|
||||||
"nan": "^2.6.2",
|
"nan": "^2.6.2",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.3.0",
|
||||||
"tar": "^3.1.3"
|
"simple-get": "^2.7.0",
|
||||||
|
"tar": "^3.1.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"async": "^2.4.1",
|
"async": "^2.5.0",
|
||||||
"cc": "^1.0.1",
|
"cc": "^1.0.1",
|
||||||
"documentation": "^4.0.0-rc.1",
|
"documentation": "^4.0.0-rc.1",
|
||||||
"exif-reader": "^1.0.2",
|
"exif-reader": "^1.0.2",
|
||||||
"icc": "^1.0.0",
|
"icc": "^1.0.0",
|
||||||
"mocha": "^3.4.2",
|
"mocha": "^3.4.2",
|
||||||
"nyc": "^10.3.2",
|
"nyc": "^11.0.3",
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
"semistandard": "^11.0.0",
|
"semistandard": "^11.0.0",
|
||||||
"unzip": "^0.1.11"
|
"unzip": "^0.1.11"
|
||||||
@@ -91,7 +93,7 @@
|
|||||||
"libvips": "8.5.5"
|
"libvips": "8.5.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4.5.0"
|
||||||
},
|
},
|
||||||
"semistandard": {
|
"semistandard": {
|
||||||
"env": [
|
"env": [
|
||||||
|
|||||||
@@ -438,9 +438,11 @@ namespace sharp {
|
|||||||
// Southeast
|
// Southeast
|
||||||
left = inWidth - outWidth;
|
left = inWidth - outWidth;
|
||||||
top = inHeight - outHeight;
|
top = inHeight - outHeight;
|
||||||
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// Southwest
|
// Southwest
|
||||||
top = inHeight - outHeight;
|
top = inHeight - outHeight;
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// Northwest
|
// Northwest
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -83,8 +83,11 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
VipsAngle rotation;
|
VipsAngle rotation;
|
||||||
if (baton->useExifOrientation) {
|
if (baton->useExifOrientation) {
|
||||||
// Rotate and flip image according to Exif orientation
|
// Rotate and flip image according to Exif orientation
|
||||||
// (ignore the requested rotation and flip)
|
bool flip;
|
||||||
std::tie(rotation, baton->flip, baton->flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
bool flop;
|
||||||
|
std::tie(rotation, flip, flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
||||||
|
baton->flip = baton->flip || flip;
|
||||||
|
baton->flop = baton->flop || flop;
|
||||||
} else {
|
} else {
|
||||||
rotation = CalculateAngleRotation(baton->angle);
|
rotation = CalculateAngleRotation(baton->angle);
|
||||||
}
|
}
|
||||||
@@ -217,12 +220,12 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If integral x and y shrink are equal, try to use shrink-on-load for JPEG and WebP,
|
// If integral x and y shrink are equal, try to use shrink-on-load for JPEG and WebP,
|
||||||
// but not when applying gamma correction or pre-resize extract
|
// but not when applying gamma correction, pre-resize extract or trim
|
||||||
int shrink_on_load = 1;
|
int shrink_on_load = 1;
|
||||||
if (
|
if (
|
||||||
xshrink == yshrink && xshrink >= 2 &&
|
xshrink == yshrink && xshrink >= 2 &&
|
||||||
(inputImageType == ImageType::JPEG || inputImageType == ImageType::WEBP) &&
|
(inputImageType == ImageType::JPEG || inputImageType == ImageType::WEBP) &&
|
||||||
baton->gamma == 0 && baton->topOffsetPre == -1
|
baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimTolerance == 0
|
||||||
) {
|
) {
|
||||||
if (xshrink >= 8) {
|
if (xshrink >= 8) {
|
||||||
xfactor = xfactor / 8;
|
xfactor = xfactor / 8;
|
||||||
@@ -808,7 +811,9 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
->set("Q", baton->tiffQuality)
|
->set("Q", baton->tiffQuality)
|
||||||
->set("squash", baton->tiffSquash)
|
->set("squash", baton->tiffSquash)
|
||||||
->set("compression", baton->tiffCompression)
|
->set("compression", baton->tiffCompression)
|
||||||
->set("predictor", baton->tiffPredictor)));
|
->set("predictor", baton->tiffPredictor)
|
||||||
|
->set("xres", baton->tiffXres)
|
||||||
|
->set("yres", baton->tiffYres)));
|
||||||
baton->bufferOut = static_cast<char*>(area->data);
|
baton->bufferOut = static_cast<char*>(area->data);
|
||||||
baton->bufferOutLength = area->length;
|
baton->bufferOutLength = area->length;
|
||||||
area->free_fn = nullptr;
|
area->free_fn = nullptr;
|
||||||
@@ -904,7 +909,9 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
->set("Q", baton->tiffQuality)
|
->set("Q", baton->tiffQuality)
|
||||||
->set("squash", baton->tiffSquash)
|
->set("squash", baton->tiffSquash)
|
||||||
->set("compression", baton->tiffCompression)
|
->set("compression", baton->tiffCompression)
|
||||||
->set("predictor", baton->tiffPredictor));
|
->set("predictor", baton->tiffPredictor)
|
||||||
|
->set("xres", baton->tiffXres)
|
||||||
|
->set("yres", baton->tiffYres));
|
||||||
baton->formatOut = "tiff";
|
baton->formatOut = "tiff";
|
||||||
baton->channels = std::min(baton->channels, 3);
|
baton->channels = std::min(baton->channels, 3);
|
||||||
} else if (baton->formatOut == "dz" || isDz || isDzZip) {
|
} else if (baton->formatOut == "dz" || isDz || isDzZip) {
|
||||||
@@ -1277,6 +1284,8 @@ NAN_METHOD(pipeline) {
|
|||||||
baton->webpNearLossless = AttrTo<bool>(options, "webpNearLossless");
|
baton->webpNearLossless = AttrTo<bool>(options, "webpNearLossless");
|
||||||
baton->tiffQuality = AttrTo<uint32_t>(options, "tiffQuality");
|
baton->tiffQuality = AttrTo<uint32_t>(options, "tiffQuality");
|
||||||
baton->tiffSquash = AttrTo<bool>(options, "tiffSquash");
|
baton->tiffSquash = AttrTo<bool>(options, "tiffSquash");
|
||||||
|
baton->tiffXres = AttrTo<double>(options, "tiffXres");
|
||||||
|
baton->tiffYres = AttrTo<double>(options, "tiffYres");
|
||||||
// tiff compression options
|
// tiff compression options
|
||||||
baton->tiffCompression = static_cast<VipsForeignTiffCompression>(
|
baton->tiffCompression = static_cast<VipsForeignTiffCompression>(
|
||||||
vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_TIFF_COMPRESSION,
|
vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_TIFF_COMPRESSION,
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ struct PipelineBaton {
|
|||||||
VipsForeignTiffCompression tiffCompression;
|
VipsForeignTiffCompression tiffCompression;
|
||||||
VipsForeignTiffPredictor tiffPredictor;
|
VipsForeignTiffPredictor tiffPredictor;
|
||||||
bool tiffSquash;
|
bool tiffSquash;
|
||||||
|
double tiffXres;
|
||||||
|
double tiffYres;
|
||||||
std::string err;
|
std::string err;
|
||||||
bool withMetadata;
|
bool withMetadata;
|
||||||
int withMetadataOrientation;
|
int withMetadataOrientation;
|
||||||
@@ -182,6 +184,8 @@ struct PipelineBaton {
|
|||||||
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
|
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
|
||||||
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_NONE),
|
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_NONE),
|
||||||
tiffSquash(false),
|
tiffSquash(false),
|
||||||
|
tiffXres(1.0),
|
||||||
|
tiffYres(1.0),
|
||||||
withMetadata(false),
|
withMetadata(false),
|
||||||
withMetadataOrientation(-1),
|
withMetadataOrientation(-1),
|
||||||
convKernelWidth(0),
|
convKernelWidth(0),
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
"test": "node perf && node random && node parallel"
|
"test": "node perf && node random && node parallel"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"async": "^2.1.4",
|
"async": "^2.5.0",
|
||||||
"benchmark": "^2.1.2",
|
"benchmark": "^2.1.4",
|
||||||
"gm": "^1.23.0",
|
"gm": "^1.23.0",
|
||||||
"imagemagick": "^0.1.3",
|
"imagemagick": "^0.1.3",
|
||||||
"imagemagick-native": "^1.9.3",
|
"imagemagick-native": "^1.9.3",
|
||||||
"images": "^3.0.0",
|
"images": "^3.0.0",
|
||||||
"jimp": "^0.2.27",
|
"jimp": "^0.2.28",
|
||||||
"mapnik": "^3.6.0",
|
"mapnik": "^3.6.2",
|
||||||
"pajk-lwip": "^0.2.0",
|
"pajk-lwip": "^0.2.0",
|
||||||
"semver": "^5.3.0"
|
"semver": "^5.3.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,12 @@ const gm = require('gm');
|
|||||||
const imagemagick = require('imagemagick');
|
const imagemagick = require('imagemagick');
|
||||||
const mapnik = require('mapnik');
|
const mapnik = require('mapnik');
|
||||||
const jimp = require('jimp');
|
const jimp = require('jimp');
|
||||||
const images = require('images');
|
let images;
|
||||||
|
try {
|
||||||
|
images = require('images');
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Excluding node-images');
|
||||||
|
}
|
||||||
let imagemagickNative;
|
let imagemagickNative;
|
||||||
try {
|
try {
|
||||||
imagemagickNative = require('imagemagick-native');
|
imagemagickNative = require('imagemagick-native');
|
||||||
@@ -268,11 +273,13 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// images
|
// images
|
||||||
jpegSuite.add('images-file-file', function () {
|
if (typeof images !== 'undefined') {
|
||||||
images(fixtures.inputJpg)
|
jpegSuite.add('images-file-file', function () {
|
||||||
.resize(width, height)
|
images(fixtures.inputJpg)
|
||||||
.save(fixtures.outputJpg, { quality: 80 });
|
.resize(width, height)
|
||||||
});
|
.save(fixtures.outputJpg, { quality: 80 });
|
||||||
|
});
|
||||||
|
}
|
||||||
// sharp
|
// sharp
|
||||||
jpegSuite.add('sharp-buffer-file', {
|
jpegSuite.add('sharp-buffer-file', {
|
||||||
defer: true,
|
defer: true,
|
||||||
@@ -827,11 +834,13 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// images
|
// images
|
||||||
pngSuite.add('images-file-file', function () {
|
if (typeof images !== 'undefined') {
|
||||||
images(fixtures.inputPng)
|
pngSuite.add('images-file-file', function () {
|
||||||
.resize(width, height)
|
images(fixtures.inputPng)
|
||||||
.save(fixtures.outputPng);
|
.resize(width, height)
|
||||||
});
|
.save(fixtures.outputPng);
|
||||||
|
});
|
||||||
|
}
|
||||||
// sharp
|
// sharp
|
||||||
pngSuite.add('sharp-buffer-file', {
|
pngSuite.add('sharp-buffer-file', {
|
||||||
defer: true,
|
defer: true,
|
||||||
|
|||||||
BIN
test/fixtures/alpha-layer-2-ink.jpg
vendored
Normal file
BIN
test/fixtures/alpha-layer-2-ink.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
BIN
test/fixtures/expected/alpha-layer-2-trim-resize.jpg
vendored
Normal file
BIN
test/fixtures/expected/alpha-layer-2-trim-resize.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
BIN
test/fixtures/expected/rotate-and-flip.jpg
vendored
Normal file
BIN
test/fixtures/expected/rotate-and-flip.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
test/fixtures/expected/rotate-and-flop.jpg
vendored
Normal file
BIN
test/fixtures/expected/rotate-and-flop.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@@ -65,6 +65,7 @@ module.exports = {
|
|||||||
inputJpgWithLowContrast: getPath('low-contrast.jpg'), // http://www.flickr.com/photos/grizdave/2569067123/
|
inputJpgWithLowContrast: getPath('low-contrast.jpg'), // http://www.flickr.com/photos/grizdave/2569067123/
|
||||||
inputJpgLarge: getPath('giant-image.jpg'),
|
inputJpgLarge: getPath('giant-image.jpg'),
|
||||||
inputJpg320x240: getPath('320x240.jpg'), // http://www.andrewault.net/2010/01/26/create-a-test-pattern-video-with-perl/
|
inputJpg320x240: getPath('320x240.jpg'), // http://www.andrewault.net/2010/01/26/create-a-test-pattern-video-with-perl/
|
||||||
|
inputJpgOverlayLayer2: getPath('alpha-layer-2-ink.jpg'),
|
||||||
|
|
||||||
inputPng: getPath('50020484-00001.png'), // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
|
inputPng: getPath('50020484-00001.png'), // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
|
||||||
inputPngWithTransparency: getPath('blackbug.png'), // public domain
|
inputPngWithTransparency: getPath('blackbug.png'), // public domain
|
||||||
|
|||||||
@@ -933,6 +933,53 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('TIFF setting xres and yres on file', function (done) {
|
||||||
|
const res = 1000.0; // inputTiff has a dpi of 300 (res*2.54)
|
||||||
|
sharp(fixtures.inputTiff)
|
||||||
|
.tiff({
|
||||||
|
xres: (res),
|
||||||
|
yres: (res)
|
||||||
|
})
|
||||||
|
.toFile(fixtures.outputTiff, (err, info) => {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('tiff', info.format);
|
||||||
|
sharp(fixtures.outputTiff).metadata(function (err, metadata) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(metadata.density, res * 2.54); // convert to dpi
|
||||||
|
fs.unlink(fixtures.outputTiff, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF setting xres and yres on buffer', function (done) {
|
||||||
|
const res = 1000.0; // inputTiff has a dpi of 300 (res*2.54)
|
||||||
|
sharp(fixtures.inputTiff)
|
||||||
|
.tiff({
|
||||||
|
xres: (res),
|
||||||
|
yres: (res)
|
||||||
|
})
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
sharp(data).metadata(function (err, metadata) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(metadata.density, res * 2.54); // convert to dpi
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid xres value should throw an error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ xres: '1000.0' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF invalid yres value should throw an error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ yres: '1000.0' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('TIFF lzw compression with horizontal predictor shrinks test file', function (done) {
|
it('TIFF lzw compression with horizontal predictor shrinks test file', function (done) {
|
||||||
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
const startSize = fs.statSync(fixtures.inputTiffUncompressed).size;
|
||||||
sharp(fixtures.inputTiffUncompressed)
|
sharp(fixtures.inputTiffUncompressed)
|
||||||
|
|||||||
@@ -253,4 +253,32 @@ describe('Rotation', function () {
|
|||||||
fixtures.assertSimilar(fixtures.inputJpg, data, done);
|
fixtures.assertSimilar(fixtures.inputJpg, data, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Auto-rotate and flip', function (done) {
|
||||||
|
sharp(fixtures.inputJpgWithExif)
|
||||||
|
.rotate()
|
||||||
|
.flip()
|
||||||
|
.resize(320)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(320, info.width);
|
||||||
|
assert.strictEqual(240, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('rotate-and-flip.jpg'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Auto-rotate and flop', function (done) {
|
||||||
|
sharp(fixtures.inputJpgWithExif)
|
||||||
|
.rotate()
|
||||||
|
.flop()
|
||||||
|
.resize(320)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(320, info.width);
|
||||||
|
assert.strictEqual(240, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('rotate-and-flop.jpg'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ describe('Trim borders', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Skip shrink-on-load', function (done) {
|
||||||
|
const expected = fixtures.expected('alpha-layer-2-trim-resize.jpg');
|
||||||
|
sharp(fixtures.inputJpgOverlayLayer2)
|
||||||
|
.trim()
|
||||||
|
.resize(300)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(300, info.width);
|
||||||
|
assert.strictEqual(300, info.height);
|
||||||
|
fixtures.assertSimilar(expected, data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('16-bit PNG with alpha channel', function (done) {
|
it('16-bit PNG with alpha channel', function (done) {
|
||||||
sharp(fixtures.inputPngWithTransparency16bit)
|
sharp(fixtures.inputPngWithTransparency16bit)
|
||||||
.resize(32, 32)
|
.resize(32, 32)
|
||||||
|
|||||||
Reference in New Issue
Block a user