mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Drop support for versions of Node prior to v4.
Reduce production (sub)depedency count from 93 to 50. Modernise dev tooling, e.g. use nyc, replace jshint with semistandard. Make 'npm test' command consistent across platforms.
This commit is contained in:
parent
3f5e38bb62
commit
36e636dca1
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ packaging/libvips*
|
|||||||
packaging/*.log
|
packaging/*.log
|
||||||
!packaging/build
|
!packaging/build
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.nyc_output
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
node_modules
|
|
||||||
test/bench/node_modules
|
|
||||||
test/saliency/humanae/node_modules
|
|
||||||
coverage
|
|
12
.jshintrc
12
.jshintrc
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"strict": true,
|
|
||||||
"node": true,
|
|
||||||
"maxparams": 4,
|
|
||||||
"maxcomplexity": 14,
|
|
||||||
"globals": {
|
|
||||||
"beforeEach": true,
|
|
||||||
"afterEach": true,
|
|
||||||
"describe": true,
|
|
||||||
"it": true
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,3 +14,4 @@ lib
|
|||||||
include
|
include
|
||||||
packaging
|
packaging
|
||||||
preinstall.sh
|
preinstall.sh
|
||||||
|
.nyc_output
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
|
||||||
- "0.12"
|
|
||||||
- "4"
|
- "4"
|
||||||
- "6"
|
- "6"
|
||||||
|
- "7"
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
@ -18,4 +17,5 @@ osx_image: xcode8
|
|||||||
before_install:
|
before_install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=g++-4.8; fi
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=g++-4.8; fi
|
||||||
after_success:
|
after_success:
|
||||||
|
- npm install coveralls
|
||||||
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
|
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
|
||||||
|
@ -3,14 +3,13 @@ version: "{build}"
|
|||||||
build: off
|
build: off
|
||||||
platform: x64
|
platform: x64
|
||||||
environment:
|
environment:
|
||||||
VIPS_WARNING: 0
|
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: "0.12"
|
|
||||||
- nodejs_version: "4"
|
- nodejs_version: "4"
|
||||||
- nodejs_version: "6"
|
- nodejs_version: "6"
|
||||||
|
- nodejs_version: "7"
|
||||||
install:
|
install:
|
||||||
- ps: Install-Product node $env:nodejs_version x64
|
- ps: Install-Product node $env:nodejs_version x64
|
||||||
- npm install -g npm@latest
|
- npm install -g npm@latest
|
||||||
- npm install
|
- npm install
|
||||||
test_script:
|
test_script:
|
||||||
- npm run-script test-win
|
- npm test
|
||||||
|
132
binding.js
132
binding.js
@ -1,81 +1,58 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var fs = require('fs');
|
const fs = require('fs');
|
||||||
var path = require('path');
|
const os = require('os');
|
||||||
var zlib = require('zlib');
|
const path = require('path');
|
||||||
|
const zlib = require('zlib');
|
||||||
|
|
||||||
var semver = require('semver');
|
const caw = require('caw');
|
||||||
var request = require('request');
|
const got = require('got');
|
||||||
var tar = require('tar');
|
const semver = require('semver');
|
||||||
|
const tar = require('tar');
|
||||||
|
|
||||||
var tmp = require('os').tmpdir();
|
const distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';
|
||||||
|
|
||||||
var distBaseUrl = '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
|
||||||
var 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;
|
||||||
|
|
||||||
var vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');
|
const platform = process.env.npm_config_platform || process.platform;
|
||||||
|
|
||||||
var platform = process.env.npm_config_platform || process.platform;
|
const arch = process.env.npm_config_arch || process.arch;
|
||||||
|
|
||||||
var arch = process.env.npm_config_arch || process.arch;
|
|
||||||
var arm_version = process.env.npm_config_armv || process.config.variables.arm_version;
|
|
||||||
|
|
||||||
if (arch === 'arch64' || arch === 'armhf') {
|
|
||||||
arch = 'arm';
|
|
||||||
if (arch === 'arch64') arm_version = '8';
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Helpers
|
// -- Helpers
|
||||||
|
|
||||||
// Does this file exist?
|
// Does this file exist?
|
||||||
var isFile = function(file) {
|
const isFile = function (file) {
|
||||||
var exists = false;
|
|
||||||
try {
|
try {
|
||||||
exists = fs.statSync(file).isFile();
|
return fs.statSync(file).isFile();
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
return exists;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var unpack = function(tarPath, done) {
|
const unpack = function (tarPath, done) {
|
||||||
var extractor = tar.Extract({
|
const extractor = tar.Extract({ path: __dirname });
|
||||||
path: __dirname
|
if (done) {
|
||||||
});
|
extractor.on('end', done);
|
||||||
|
}
|
||||||
extractor.on('error', error);
|
extractor.on('error', error);
|
||||||
extractor.on('end', function() {
|
fs.createReadStream(tarPath)
|
||||||
if (!isFile(vipsHeaderPath)) {
|
.on('error', error)
|
||||||
error('Could not unpack ' + tarPath);
|
|
||||||
}
|
|
||||||
if (typeof done === 'function') {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fs.createReadStream(tarPath).on('error', error)
|
|
||||||
.pipe(zlib.Unzip())
|
.pipe(zlib.Unzip())
|
||||||
.pipe(extractor);
|
.pipe(extractor);
|
||||||
};
|
};
|
||||||
|
|
||||||
var platformId = function() {
|
const platformId = function () {
|
||||||
var id = [platform, arch].join('-');
|
const platformId = [platform];
|
||||||
if (arch === 'arm') {
|
if (arch === 'arm' || arch === 'armhf' || arch === 'arch64') {
|
||||||
switch(arm_version) {
|
const armVersion = (arch === 'arch64') ? '8' : process.env.npm_config_armv || process.config.variables.arm_version || '6';
|
||||||
case '8':
|
platformId.push('armv' + armVersion);
|
||||||
id = id + 'v8';
|
} else {
|
||||||
break;
|
platformId.push(arch);
|
||||||
case '7':
|
|
||||||
id = id + 'v7';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
id = id + 'v6';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return platformId.join('-');
|
||||||
return id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
var error = function(msg) {
|
const error = function (msg) {
|
||||||
if (msg instanceof Error) {
|
if (msg instanceof Error) {
|
||||||
msg = msg.message;
|
msg = msg.message;
|
||||||
}
|
}
|
||||||
@ -85,18 +62,19 @@ var error = function(msg) {
|
|||||||
|
|
||||||
// -- Binary downloaders
|
// -- Binary downloaders
|
||||||
|
|
||||||
module.exports.download_vips = function() {
|
module.exports.download_vips = function () {
|
||||||
// Has vips been installed locally?
|
// Has vips been installed locally?
|
||||||
|
const vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');
|
||||||
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 - please see http://sharp.dimens.io/en/stable/install/');
|
||||||
}
|
}
|
||||||
// Ensure glibc >= 2.15
|
// Ensure glibc >= 2.15
|
||||||
var lddVersion = process.env.LDD_VERSION;
|
const lddVersion = process.env.LDD_VERSION;
|
||||||
if (lddVersion) {
|
if (lddVersion) {
|
||||||
if (/(glibc|gnu libc)/i.test(lddVersion)) {
|
if (/(glibc|gnu libc)/i.test(lddVersion)) {
|
||||||
var glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
|
const glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
|
||||||
if (glibcVersion && semver.lt(glibcVersion + '.0', '2.13.0')) {
|
if (glibcVersion && semver.lt(glibcVersion + '.0', '2.13.0')) {
|
||||||
error('glibc version ' + glibcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
error('glibc version ' + glibcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
||||||
}
|
}
|
||||||
@ -105,47 +83,47 @@ module.exports.download_vips = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Arch/platform-specific .tar.gz
|
// Arch/platform-specific .tar.gz
|
||||||
var tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
|
const tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
|
||||||
var tarPath = path.join(__dirname, 'packaging', tarFilename);
|
const tarPathLocal = path.join(__dirname, 'packaging', tarFilename);
|
||||||
if (isFile(tarPath)) {
|
if (isFile(tarPathLocal)) {
|
||||||
unpack(tarPath);
|
unpack(tarPathLocal);
|
||||||
} else {
|
} else {
|
||||||
// Download to per-process temporary file
|
// Download to per-process temporary file
|
||||||
tarPath = path.join(tmp, process.pid + '-' + tarFilename);
|
const tarPathTemp = path.join(os.tmpdir(), process.pid + '-' + tarFilename);
|
||||||
var tmpFile = fs.createWriteStream(tarPath).on('finish', function() {
|
const tmpFile = fs.createWriteStream(tarPathTemp).on('finish', function () {
|
||||||
unpack(tarPath, function() {
|
unpack(tarPathTemp, function () {
|
||||||
// Attempt to remove temporary file
|
// Attempt to remove temporary file
|
||||||
try {
|
try {
|
||||||
fs.unlinkSync(tarPath);
|
fs.unlinkSync(tarPathTemp);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var options = {
|
const gotOpt = {};
|
||||||
url: distBaseUrl + tarFilename
|
|
||||||
};
|
|
||||||
if (process.env.npm_config_https_proxy) {
|
if (process.env.npm_config_https_proxy) {
|
||||||
// Use the NPM-configured HTTPS proxy
|
// Use the NPM-configured HTTPS proxy
|
||||||
options.proxy = process.env.npm_config_https_proxy;
|
gotOpt.agent = caw(process.env.npm_config_https_proxy);
|
||||||
}
|
}
|
||||||
request(options).on('response', function(response) {
|
const url = distBaseUrl + tarFilename;
|
||||||
|
got.stream(url, gotOpt).on('response', function (response) {
|
||||||
if (response.statusCode !== 200) {
|
if (response.statusCode !== 200) {
|
||||||
error(distBaseUrl + tarFilename + ' status code ' + response.statusCode);
|
error(url + ' status code ' + response.statusCode);
|
||||||
}
|
}
|
||||||
}).on('error', function(err) {
|
}).on('error', function (err) {
|
||||||
error('Download from ' + distBaseUrl + tarFilename + ' failed: ' + err.message);
|
error('Download of ' + url + ' failed: ' + err.message);
|
||||||
}).pipe(tmpFile);
|
}).pipe(tmpFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.use_global_vips = function() {
|
module.exports.use_global_vips = function () {
|
||||||
var useGlobalVips = false;
|
const globalVipsVersion = process.env.GLOBAL_VIPS_VERSION;
|
||||||
var globalVipsVersion = process.env.GLOBAL_VIPS_VERSION;
|
|
||||||
if (globalVipsVersion) {
|
if (globalVipsVersion) {
|
||||||
useGlobalVips = semver.gte(
|
const useGlobalVips = semver.gte(
|
||||||
globalVipsVersion,
|
globalVipsVersion,
|
||||||
minimumLibvipsVersion
|
minimumLibvipsVersion
|
||||||
);
|
);
|
||||||
}
|
|
||||||
process.stdout.write(useGlobalVips ? 'true' : 'false');
|
process.stdout.write(useGlobalVips ? 'true' : 'false');
|
||||||
|
} else {
|
||||||
|
process.stdout.write('false');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
### v0.17 - "*quill*"
|
### v0.17 - "*quill*"
|
||||||
|
|
||||||
Requires libvips v8.4.2
|
Requires libvips v8.4.2.
|
||||||
|
|
||||||
#### v0.17.0 - TBD
|
#### v0.17.0 - TBD
|
||||||
|
|
||||||
|
* Drop support for versions of Node prior to v4.
|
||||||
|
|
||||||
* Deprecate the following output format "option" functions:
|
* Deprecate the following output format "option" functions:
|
||||||
quality, progressive, compressionLevel, withoutAdaptiveFiltering,
|
quality, progressive, compressionLevel, withoutAdaptiveFiltering,
|
||||||
withoutChromaSubsampling, trellisQuantisation, trellisQuantization,
|
withoutChromaSubsampling, trellisQuantisation, trellisQuantization,
|
||||||
|
279
index.js
279
index.js
@ -1,23 +1,22 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
const path = require('path');
|
||||||
var util = require('util');
|
const util = require('util');
|
||||||
var stream = require('stream');
|
const stream = require('stream');
|
||||||
var events = require('events');
|
const events = require('events');
|
||||||
|
|
||||||
var semver = require('semver');
|
const semver = require('semver');
|
||||||
var color = require('color');
|
const color = require('color');
|
||||||
var BluebirdPromise = require('bluebird');
|
|
||||||
|
|
||||||
var sharp = require('./build/Release/sharp.node');
|
const sharp = require('./build/Release/sharp.node');
|
||||||
|
|
||||||
// Versioning
|
// Versioning
|
||||||
var versions = {
|
let versions = {
|
||||||
vips: sharp.libvipsVersion()
|
vips: sharp.libvipsVersion()
|
||||||
};
|
};
|
||||||
(function() {
|
(function () {
|
||||||
// Does libvips meet minimum requirement?
|
// Does libvips meet minimum requirement?
|
||||||
var libvipsVersionMin = require('./package.json').config.libvips;
|
const libvipsVersionMin = require('./package.json').config.libvips;
|
||||||
if (semver.lt(versions.vips, libvipsVersionMin)) {
|
if (semver.lt(versions.vips, libvipsVersionMin)) {
|
||||||
throw new Error('Found libvips ' + versions.vips + ' but require at least ' + libvipsVersionMin);
|
throw new Error('Found libvips ' + versions.vips + ' but require at least ' + libvipsVersionMin);
|
||||||
}
|
}
|
||||||
@ -28,14 +27,14 @@ var versions = {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
// Limits
|
// Limits
|
||||||
var maximum = {
|
const maximum = {
|
||||||
width: 0x3FFF,
|
width: 0x3FFF,
|
||||||
height: 0x3FFF,
|
height: 0x3FFF,
|
||||||
pixels: Math.pow(0x3FFF, 2)
|
pixels: Math.pow(0x3FFF, 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructor-factory
|
// Constructor-factory
|
||||||
var Sharp = function(input, options) {
|
const Sharp = function (input, options) {
|
||||||
if (!(this instanceof Sharp)) {
|
if (!(this instanceof Sharp)) {
|
||||||
return new Sharp(input, options);
|
return new Sharp(input, options);
|
||||||
}
|
}
|
||||||
@ -91,8 +90,8 @@ var Sharp = function(input, options) {
|
|||||||
colourspace: 'srgb',
|
colourspace: 'srgb',
|
||||||
// overlay
|
// overlay
|
||||||
overlayGravity: 0,
|
overlayGravity: 0,
|
||||||
overlayXOffset : -1,
|
overlayXOffset: -1,
|
||||||
overlayYOffset : -1,
|
overlayYOffset: -1,
|
||||||
overlayTile: false,
|
overlayTile: false,
|
||||||
overlayCutout: false,
|
overlayCutout: false,
|
||||||
// output
|
// output
|
||||||
@ -116,7 +115,7 @@ var Sharp = function(input, options) {
|
|||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
tileOverlap: 0,
|
tileOverlap: 0,
|
||||||
// Function to notify of queue length changes
|
// Function to notify of queue length changes
|
||||||
queueListener: function(queueLength) {
|
queueListener: function (queueLength) {
|
||||||
module.exports.queue.emit('change', queueLength);
|
module.exports.queue.emit('change', queueLength);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -144,42 +143,42 @@ module.exports.versions = versions;
|
|||||||
/*
|
/*
|
||||||
Validation helpers
|
Validation helpers
|
||||||
*/
|
*/
|
||||||
var isDefined = function(val) {
|
const isDefined = function (val) {
|
||||||
return typeof val !== 'undefined' && val !== null;
|
return typeof val !== 'undefined' && val !== null;
|
||||||
};
|
};
|
||||||
var isObject = function(val) {
|
const isObject = function (val) {
|
||||||
return typeof val === 'object';
|
return typeof val === 'object';
|
||||||
};
|
};
|
||||||
var isFunction = function(val) {
|
const isFunction = function (val) {
|
||||||
return typeof val === 'function';
|
return typeof val === 'function';
|
||||||
};
|
};
|
||||||
var isBoolean = function(val) {
|
const isBoolean = function (val) {
|
||||||
return typeof val === 'boolean';
|
return typeof val === 'boolean';
|
||||||
};
|
};
|
||||||
var isBuffer = function(val) {
|
const isBuffer = function (val) {
|
||||||
return typeof val === 'object' && val instanceof Buffer;
|
return typeof val === 'object' && val instanceof Buffer;
|
||||||
};
|
};
|
||||||
var isString = function(val) {
|
const isString = function (val) {
|
||||||
return typeof val === 'string' && val.length > 0;
|
return typeof val === 'string' && val.length > 0;
|
||||||
};
|
};
|
||||||
var isNumber = function(val) {
|
const isNumber = function (val) {
|
||||||
return typeof val === 'number' && !Number.isNaN(val);
|
return typeof val === 'number' && !Number.isNaN(val);
|
||||||
};
|
};
|
||||||
var isInteger = function(val) {
|
const isInteger = function (val) {
|
||||||
return isNumber(val) && val % 1 === 0;
|
return isNumber(val) && val % 1 === 0;
|
||||||
};
|
};
|
||||||
var inRange = function(val, min, max) {
|
const inRange = function (val, min, max) {
|
||||||
return val >= min && val <= max;
|
return val >= min && val <= max;
|
||||||
};
|
};
|
||||||
var contains = function(val, list) {
|
const contains = function (val, list) {
|
||||||
return list.indexOf(val) !== -1;
|
return list.indexOf(val) !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create Object containing input and input-related options
|
Create Object containing input and input-related options
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._createInputDescriptor = function(input, inputOptions, containerOptions) {
|
Sharp.prototype._createInputDescriptor = function (input, inputOptions, containerOptions) {
|
||||||
var inputDescriptor = {};
|
const inputDescriptor = {};
|
||||||
if (isString(input)) {
|
if (isString(input)) {
|
||||||
// filesystem
|
// filesystem
|
||||||
inputDescriptor.file = input;
|
inputDescriptor.file = input;
|
||||||
@ -225,8 +224,7 @@ Sharp.prototype._createInputDescriptor = function(input, inputOptions, container
|
|||||||
/*
|
/*
|
||||||
Handle incoming chunk on Writable Stream
|
Handle incoming chunk on Writable Stream
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._write = function(chunk, encoding, callback) {
|
Sharp.prototype._write = function (chunk, encoding, callback) {
|
||||||
/*jslint unused: false */
|
|
||||||
if (Array.isArray(this.options.input.buffer)) {
|
if (Array.isArray(this.options.input.buffer)) {
|
||||||
if (isBuffer(chunk)) {
|
if (isBuffer(chunk)) {
|
||||||
this.options.input.buffer.push(chunk);
|
this.options.input.buffer.push(chunk);
|
||||||
@ -242,12 +240,12 @@ Sharp.prototype._write = function(chunk, encoding, callback) {
|
|||||||
/*
|
/*
|
||||||
Flattens the array of chunks accumulated in input.buffer
|
Flattens the array of chunks accumulated in input.buffer
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._flattenBufferIn = function() {
|
Sharp.prototype._flattenBufferIn = function () {
|
||||||
if (this._isStreamInput()) {
|
if (this._isStreamInput()) {
|
||||||
this.options.input.buffer = Buffer.concat(this.options.input.buffer);
|
this.options.input.buffer = Buffer.concat(this.options.input.buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Sharp.prototype._isStreamInput = function() {
|
Sharp.prototype._isStreamInput = function () {
|
||||||
return Array.isArray(this.options.input.buffer);
|
return Array.isArray(this.options.input.buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -274,7 +272,7 @@ module.exports.strategy = {
|
|||||||
/*
|
/*
|
||||||
What part of the image should be retained when cropping?
|
What part of the image should be retained when cropping?
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.crop = function(crop) {
|
Sharp.prototype.crop = function (crop) {
|
||||||
this.options.canvas = 'crop';
|
this.options.canvas = 'crop';
|
||||||
if (!isDefined(crop)) {
|
if (!isDefined(crop)) {
|
||||||
// Default
|
// Default
|
||||||
@ -294,10 +292,10 @@ Sharp.prototype.crop = function(crop) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.extract = function(options) {
|
Sharp.prototype.extract = function (options) {
|
||||||
var suffix = this.options.width === -1 && this.options.height === -1 ? 'Pre' : 'Post';
|
const suffix = this.options.width === -1 && this.options.height === -1 ? 'Pre' : 'Post';
|
||||||
['left', 'top', 'width', 'height'].forEach(function (name) {
|
['left', 'top', 'width', 'height'].forEach(function (name) {
|
||||||
var value = options[name];
|
const value = options[name];
|
||||||
if (isInteger(value) && value >= 0) {
|
if (isInteger(value) && value >= 0) {
|
||||||
this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
|
this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
|
||||||
} else {
|
} else {
|
||||||
@ -311,14 +309,15 @@ Sharp.prototype.extract = function(options) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.extractChannel = function(channel) {
|
Sharp.prototype.extractChannel = function (channel) {
|
||||||
if (channel === 'red')
|
if (channel === 'red') {
|
||||||
channel = 0;
|
channel = 0;
|
||||||
else if (channel === 'green')
|
} else if (channel === 'green') {
|
||||||
channel = 1;
|
channel = 1;
|
||||||
else if (channel === 'blue')
|
} else if (channel === 'blue') {
|
||||||
channel = 2;
|
channel = 2;
|
||||||
if(isInteger(channel) && inRange(channel,0,4)) {
|
}
|
||||||
|
if (isInteger(channel) && inRange(channel, 0, 4)) {
|
||||||
this.options.extractChannel = channel;
|
this.options.extractChannel = channel;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Cannot extract invalid channel ' + channel);
|
throw new Error('Cannot extract invalid channel ' + channel);
|
||||||
@ -331,24 +330,24 @@ Sharp.prototype.extractChannel = function(channel) {
|
|||||||
Delegates to the 'Color' module, which can throw an Error
|
Delegates to the 'Color' module, which can throw an Error
|
||||||
but is liberal in what it accepts, clamping values to sensible min/max.
|
but is liberal in what it accepts, clamping values to sensible min/max.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.background = function(rgba) {
|
Sharp.prototype.background = function (rgba) {
|
||||||
var colour = color(rgba);
|
const colour = color(rgba);
|
||||||
this.options.background = colour.rgbArray();
|
this.options.background = colour.rgbArray();
|
||||||
this.options.background.push(colour.alpha() * 255);
|
this.options.background.push(colour.alpha() * 255);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.embed = function() {
|
Sharp.prototype.embed = function () {
|
||||||
this.options.canvas = 'embed';
|
this.options.canvas = 'embed';
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.max = function() {
|
Sharp.prototype.max = function () {
|
||||||
this.options.canvas = 'max';
|
this.options.canvas = 'max';
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.min = function() {
|
Sharp.prototype.min = function () {
|
||||||
this.options.canvas = 'min';
|
this.options.canvas = 'min';
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -357,17 +356,17 @@ Sharp.prototype.min = function() {
|
|||||||
Ignoring the aspect ratio of the input, stretch the image to
|
Ignoring the aspect ratio of the input, stretch the image to
|
||||||
the exact width and/or height provided via the resize method.
|
the exact width and/or height provided via the resize method.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.ignoreAspectRatio = function() {
|
Sharp.prototype.ignoreAspectRatio = function () {
|
||||||
this.options.canvas = 'ignore_aspect';
|
this.options.canvas = 'ignore_aspect';
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.flatten = function(flatten) {
|
Sharp.prototype.flatten = function (flatten) {
|
||||||
this.options.flatten = isBoolean(flatten) ? flatten : true;
|
this.options.flatten = isBoolean(flatten) ? flatten : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.negate = function(negate) {
|
Sharp.prototype.negate = function (negate) {
|
||||||
this.options.negate = isBoolean(negate) ? negate : true;
|
this.options.negate = isBoolean(negate) ? negate : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -375,7 +374,7 @@ Sharp.prototype.negate = function(negate) {
|
|||||||
/*
|
/*
|
||||||
Bitwise boolean operations between images
|
Bitwise boolean operations between images
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.boolean = function(operand, operator, options) {
|
Sharp.prototype.boolean = function (operand, operator, options) {
|
||||||
this.options.boolean = this._createInputDescriptor(operand, options);
|
this.options.boolean = this._createInputDescriptor(operand, options);
|
||||||
if (isString(operator) && contains(operator, ['and', 'or', 'eor'])) {
|
if (isString(operator) && contains(operator, ['and', 'or', 'eor'])) {
|
||||||
this.options.booleanOp = operator;
|
this.options.booleanOp = operator;
|
||||||
@ -388,7 +387,7 @@ Sharp.prototype.boolean = function(operand, operator, options) {
|
|||||||
/*
|
/*
|
||||||
Overlay with another image, using an optional gravity
|
Overlay with another image, using an optional gravity
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.overlayWith = function(overlay, options) {
|
Sharp.prototype.overlayWith = function (overlay, options) {
|
||||||
this.options.overlay = this._createInputDescriptor(overlay, options, {
|
this.options.overlay = this._createInputDescriptor(overlay, options, {
|
||||||
allowStream: false
|
allowStream: false
|
||||||
});
|
});
|
||||||
@ -419,7 +418,7 @@ Sharp.prototype.overlayWith = function(overlay, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isDefined(options.gravity)) {
|
if (isDefined(options.gravity)) {
|
||||||
if(isInteger(options.gravity) && inRange(options.gravity, 0, 8)) {
|
if (isInteger(options.gravity) && inRange(options.gravity, 0, 8)) {
|
||||||
this.options.overlayGravity = options.gravity;
|
this.options.overlayGravity = options.gravity;
|
||||||
} else if (isString(options.gravity) && isInteger(module.exports.gravity[options.gravity])) {
|
} else if (isString(options.gravity) && isInteger(module.exports.gravity[options.gravity])) {
|
||||||
this.options.overlayGravity = module.exports.gravity[options.gravity];
|
this.options.overlayGravity = module.exports.gravity[options.gravity];
|
||||||
@ -434,9 +433,9 @@ Sharp.prototype.overlayWith = function(overlay, options) {
|
|||||||
/*
|
/*
|
||||||
Add another color channel to the image
|
Add another color channel to the image
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.joinChannel = function(images, options) {
|
Sharp.prototype.joinChannel = function (images, options) {
|
||||||
if (Array.isArray(images)) {
|
if (Array.isArray(images)) {
|
||||||
images.forEach(function(image) {
|
images.forEach(function (image) {
|
||||||
this.options.joinChannelIn.push(this._createInputDescriptor(image, options));
|
this.options.joinChannelIn.push(this._createInputDescriptor(image, options));
|
||||||
}, this);
|
}, this);
|
||||||
} else {
|
} else {
|
||||||
@ -449,7 +448,7 @@ Sharp.prototype.joinChannel = function(images, options) {
|
|||||||
Rotate output image by 0, 90, 180 or 270 degrees
|
Rotate output image by 0, 90, 180 or 270 degrees
|
||||||
Auto-rotation based on the EXIF Orientation tag is represented by an angle of -1
|
Auto-rotation based on the EXIF Orientation tag is represented by an angle of -1
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.rotate = function(angle) {
|
Sharp.prototype.rotate = function (angle) {
|
||||||
if (!isDefined(angle)) {
|
if (!isDefined(angle)) {
|
||||||
this.options.angle = -1;
|
this.options.angle = -1;
|
||||||
} else if (isInteger(angle) && contains(angle, [0, 90, 180, 270])) {
|
} else if (isInteger(angle) && contains(angle, [0, 90, 180, 270])) {
|
||||||
@ -463,7 +462,7 @@ Sharp.prototype.rotate = function(angle) {
|
|||||||
/*
|
/*
|
||||||
Flip the image vertically, about the Y axis
|
Flip the image vertically, about the Y axis
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.flip = function(flip) {
|
Sharp.prototype.flip = function (flip) {
|
||||||
this.options.flip = isBoolean(flip) ? flip : true;
|
this.options.flip = isBoolean(flip) ? flip : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -471,7 +470,7 @@ Sharp.prototype.flip = function(flip) {
|
|||||||
/*
|
/*
|
||||||
Flop the image horizontally, about the X axis
|
Flop the image horizontally, about the X axis
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.flop = function(flop) {
|
Sharp.prototype.flop = function (flop) {
|
||||||
this.options.flop = isBoolean(flop) ? flop : true;
|
this.options.flop = isBoolean(flop) ? flop : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -481,7 +480,7 @@ Sharp.prototype.flop = function(flop) {
|
|||||||
This is equivalent to GraphicsMagick's ">" geometry option:
|
This is equivalent to GraphicsMagick's ">" geometry option:
|
||||||
"change the dimensions of the image only if its width or height exceeds the geometry specification"
|
"change the dimensions of the image only if its width or height exceeds the geometry specification"
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.withoutEnlargement = function(withoutEnlargement) {
|
Sharp.prototype.withoutEnlargement = function (withoutEnlargement) {
|
||||||
this.options.withoutEnlargement = isBoolean(withoutEnlargement) ? withoutEnlargement : true;
|
this.options.withoutEnlargement = isBoolean(withoutEnlargement) ? withoutEnlargement : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -491,7 +490,7 @@ Sharp.prototype.withoutEnlargement = function(withoutEnlargement) {
|
|||||||
Call without a sigma to use a fast, mild blur.
|
Call without a sigma to use a fast, mild blur.
|
||||||
Call with a sigma to use a slower, more accurate Gaussian blur.
|
Call with a sigma to use a slower, more accurate Gaussian blur.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.blur = function(sigma) {
|
Sharp.prototype.blur = function (sigma) {
|
||||||
if (!isDefined(sigma)) {
|
if (!isDefined(sigma)) {
|
||||||
// No arguments: default to mild blur
|
// No arguments: default to mild blur
|
||||||
this.options.blurSigma = -1;
|
this.options.blurSigma = -1;
|
||||||
@ -510,18 +509,18 @@ Sharp.prototype.blur = function(sigma) {
|
|||||||
/*
|
/*
|
||||||
Convolve the image with a kernel.
|
Convolve the image with a kernel.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.convolve = function(kernel) {
|
Sharp.prototype.convolve = function (kernel) {
|
||||||
if (!isObject(kernel) || !Array.isArray(kernel.kernel) ||
|
if (!isObject(kernel) || !Array.isArray(kernel.kernel) ||
|
||||||
!isInteger(kernel.width) || !isInteger(kernel.height) ||
|
!isInteger(kernel.width) || !isInteger(kernel.height) ||
|
||||||
!inRange(kernel.width, 3, 1001) || !inRange(kernel.height, 3, 1001) ||
|
!inRange(kernel.width, 3, 1001) || !inRange(kernel.height, 3, 1001) ||
|
||||||
kernel.height * kernel.width != kernel.kernel.length
|
kernel.height * kernel.width !== kernel.kernel.length
|
||||||
) {
|
) {
|
||||||
// must pass in a kernel
|
// must pass in a kernel
|
||||||
throw new Error('Invalid convolution kernel');
|
throw new Error('Invalid convolution kernel');
|
||||||
}
|
}
|
||||||
// Default scale is sum of kernel values
|
// Default scale is sum of kernel values
|
||||||
if (!isInteger(kernel.scale)) {
|
if (!isInteger(kernel.scale)) {
|
||||||
kernel.scale = kernel.kernel.reduce(function(a, b) {
|
kernel.scale = kernel.kernel.reduce(function (a, b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
@ -544,7 +543,7 @@ Sharp.prototype.convolve = function(kernel) {
|
|||||||
flat - level of "flat" area sharpen, default 1
|
flat - level of "flat" area sharpen, default 1
|
||||||
jagged - level of "jagged" area sharpen, default 2
|
jagged - level of "jagged" area sharpen, default 2
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.sharpen = function(sigma, flat, jagged) {
|
Sharp.prototype.sharpen = function (sigma, flat, jagged) {
|
||||||
if (!isDefined(sigma)) {
|
if (!isDefined(sigma)) {
|
||||||
// No arguments: default to mild sharpen
|
// No arguments: default to mild sharpen
|
||||||
this.options.sharpenSigma = -1;
|
this.options.sharpenSigma = -1;
|
||||||
@ -576,7 +575,7 @@ Sharp.prototype.sharpen = function(sigma, flat, jagged) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.threshold = function(threshold, options) {
|
Sharp.prototype.threshold = function (threshold, options) {
|
||||||
if (!isDefined(threshold)) {
|
if (!isDefined(threshold)) {
|
||||||
this.options.threshold = 128;
|
this.options.threshold = 128;
|
||||||
} else if (isBoolean(threshold)) {
|
} else if (isBoolean(threshold)) {
|
||||||
@ -599,7 +598,7 @@ Sharp.prototype.threshold = function(threshold, options) {
|
|||||||
tolerance - if present, is a percentaged tolerance level between 0 and 100 to trim away similar color values
|
tolerance - if present, is a percentaged tolerance level between 0 and 100 to trim away similar color values
|
||||||
Defaulting to 10 when no tolerance is given.
|
Defaulting to 10 when no tolerance is given.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.trim = function(tolerance) {
|
Sharp.prototype.trim = function (tolerance) {
|
||||||
if (!isDefined(tolerance)) {
|
if (!isDefined(tolerance)) {
|
||||||
this.options.trimTolerance = 10;
|
this.options.trimTolerance = 10;
|
||||||
} else if (isInteger(tolerance) && inRange(tolerance, 1, 99)) {
|
} else if (isInteger(tolerance) && inRange(tolerance, 1, 99)) {
|
||||||
@ -614,7 +613,7 @@ Sharp.prototype.trim = function(tolerance) {
|
|||||||
Darken image pre-resize (1/gamma) and brighten post-resize (gamma).
|
Darken image pre-resize (1/gamma) and brighten post-resize (gamma).
|
||||||
Improves brightness of resized image in non-linear colour spaces.
|
Improves brightness of resized image in non-linear colour spaces.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.gamma = function(gamma) {
|
Sharp.prototype.gamma = function (gamma) {
|
||||||
if (!isDefined(gamma)) {
|
if (!isDefined(gamma)) {
|
||||||
// Default gamma correction of 2.2 (sRGB)
|
// Default gamma correction of 2.2 (sRGB)
|
||||||
this.options.gamma = 2.2;
|
this.options.gamma = 2.2;
|
||||||
@ -629,7 +628,7 @@ Sharp.prototype.gamma = function(gamma) {
|
|||||||
/*
|
/*
|
||||||
Enhance output image contrast by stretching its luminance to cover the full dynamic range
|
Enhance output image contrast by stretching its luminance to cover the full dynamic range
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.normalize = function(normalize) {
|
Sharp.prototype.normalize = function (normalize) {
|
||||||
this.options.normalize = isBoolean(normalize) ? normalize : true;
|
this.options.normalize = isBoolean(normalize) ? normalize : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -638,7 +637,7 @@ Sharp.prototype.normalise = Sharp.prototype.normalize;
|
|||||||
/*
|
/*
|
||||||
Perform boolean/bitwise operation on image color channels - results in one channel image
|
Perform boolean/bitwise operation on image color channels - results in one channel image
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.bandbool = function(boolOp) {
|
Sharp.prototype.bandbool = function (boolOp) {
|
||||||
if (isString(boolOp) && contains(boolOp, ['and', 'or', 'eor'])) {
|
if (isString(boolOp) && contains(boolOp, ['and', 'or', 'eor'])) {
|
||||||
this.options.bandBoolOp = boolOp;
|
this.options.bandBoolOp = boolOp;
|
||||||
} else {
|
} else {
|
||||||
@ -650,7 +649,7 @@ Sharp.prototype.bandbool = function(boolOp) {
|
|||||||
/*
|
/*
|
||||||
Convert to greyscale
|
Convert to greyscale
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.greyscale = function(greyscale) {
|
Sharp.prototype.greyscale = function (greyscale) {
|
||||||
this.options.greyscale = isBoolean(greyscale) ? greyscale : true;
|
this.options.greyscale = isBoolean(greyscale) ? greyscale : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -659,8 +658,8 @@ Sharp.prototype.grayscale = Sharp.prototype.greyscale;
|
|||||||
/*
|
/*
|
||||||
Set output colourspace
|
Set output colourspace
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.toColourspace = function(colourspace) {
|
Sharp.prototype.toColourspace = function (colourspace) {
|
||||||
if (!isString(colourspace) ) {
|
if (!isString(colourspace)) {
|
||||||
throw new Error('Invalid output colourspace ' + colourspace);
|
throw new Error('Invalid output colourspace ' + colourspace);
|
||||||
}
|
}
|
||||||
this.options.colourspace = colourspace;
|
this.options.colourspace = colourspace;
|
||||||
@ -668,59 +667,59 @@ Sharp.prototype.toColourspace = function(colourspace) {
|
|||||||
};
|
};
|
||||||
Sharp.prototype.toColorspace = Sharp.prototype.toColourspace;
|
Sharp.prototype.toColorspace = Sharp.prototype.toColourspace;
|
||||||
|
|
||||||
Sharp.prototype.sequentialRead = function(sequentialRead) {
|
Sharp.prototype.sequentialRead = function (sequentialRead) {
|
||||||
this.options.sequentialRead = isBoolean(sequentialRead) ? sequentialRead : true;
|
this.options.sequentialRead = isBoolean(sequentialRead) ? sequentialRead : true;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Deprecated output options
|
// Deprecated output options
|
||||||
Sharp.prototype.quality = util.deprecate(function(quality) {
|
Sharp.prototype.quality = util.deprecate(function (quality) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
var options = { quality: quality };
|
const options = { quality: quality };
|
||||||
this.jpeg(options).webp(options).tiff(options);
|
this.jpeg(options).webp(options).tiff(options);
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'quality: use jpeg({ quality: ... }), webp({ quality: ... }) and/or tiff({ quality: ... }) instead');
|
}, 'quality: use jpeg({ quality: ... }), webp({ quality: ... }) and/or tiff({ quality: ... }) instead');
|
||||||
Sharp.prototype.progressive = util.deprecate(function(progressive) {
|
Sharp.prototype.progressive = util.deprecate(function (progressive) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
var options = { progressive: (progressive !== false) };
|
const options = { progressive: (progressive !== false) };
|
||||||
this.jpeg(options).png(options);
|
this.jpeg(options).png(options);
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'progressive: use jpeg({ progressive: ... }) and/or png({ progressive: ... }) instead');
|
}, 'progressive: use jpeg({ progressive: ... }) and/or png({ progressive: ... }) instead');
|
||||||
Sharp.prototype.compressionLevel = util.deprecate(function(compressionLevel) {
|
Sharp.prototype.compressionLevel = util.deprecate(function (compressionLevel) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
this.png({ compressionLevel: compressionLevel });
|
this.png({ compressionLevel: compressionLevel });
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'compressionLevel: use png({ compressionLevel: ... }) instead');
|
}, 'compressionLevel: use png({ compressionLevel: ... }) instead');
|
||||||
Sharp.prototype.withoutAdaptiveFiltering = util.deprecate(function(withoutAdaptiveFiltering) {
|
Sharp.prototype.withoutAdaptiveFiltering = util.deprecate(function (withoutAdaptiveFiltering) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
this.png({ adaptiveFiltering: (withoutAdaptiveFiltering === false) });
|
this.png({ adaptiveFiltering: (withoutAdaptiveFiltering === false) });
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'withoutAdaptiveFiltering: use png({ adaptiveFiltering: ... }) instead');
|
}, 'withoutAdaptiveFiltering: use png({ adaptiveFiltering: ... }) instead');
|
||||||
Sharp.prototype.withoutChromaSubsampling = util.deprecate(function(withoutChromaSubsampling) {
|
Sharp.prototype.withoutChromaSubsampling = util.deprecate(function (withoutChromaSubsampling) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
this.jpeg({ chromaSubsampling: (withoutChromaSubsampling === false) ? '4:2:0' : '4:4:4' });
|
this.jpeg({ chromaSubsampling: (withoutChromaSubsampling === false) ? '4:2:0' : '4:4:4' });
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'withoutChromaSubsampling: use jpeg({ chromaSubsampling: "4:4:4" }) instead');
|
}, 'withoutChromaSubsampling: use jpeg({ chromaSubsampling: "4:4:4" }) instead');
|
||||||
Sharp.prototype.trellisQuantisation = util.deprecate(function(trellisQuantisation) {
|
Sharp.prototype.trellisQuantisation = util.deprecate(function (trellisQuantisation) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
this.jpeg({ trellisQuantisation: (trellisQuantisation !== false) });
|
this.jpeg({ trellisQuantisation: (trellisQuantisation !== false) });
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'trellisQuantisation: use jpeg({ trellisQuantisation: ... }) instead');
|
}, 'trellisQuantisation: use jpeg({ trellisQuantisation: ... }) instead');
|
||||||
Sharp.prototype.trellisQuantization = Sharp.prototype.trellisQuantisation;
|
Sharp.prototype.trellisQuantization = Sharp.prototype.trellisQuantisation;
|
||||||
Sharp.prototype.overshootDeringing = util.deprecate(function(overshootDeringing) {
|
Sharp.prototype.overshootDeringing = util.deprecate(function (overshootDeringing) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
this.jpeg({ overshootDeringing: (overshootDeringing !== false) });
|
this.jpeg({ overshootDeringing: (overshootDeringing !== false) });
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
}, 'overshootDeringing: use jpeg({ overshootDeringing: ... }) instead');
|
}, 'overshootDeringing: use jpeg({ overshootDeringing: ... }) instead');
|
||||||
Sharp.prototype.optimiseScans = util.deprecate(function(optimiseScans) {
|
Sharp.prototype.optimiseScans = util.deprecate(function (optimiseScans) {
|
||||||
var formatOut = this.options.formatOut;
|
const formatOut = this.options.formatOut;
|
||||||
this.jpeg({ optimiseScans: (optimiseScans !== false) });
|
this.jpeg({ optimiseScans: (optimiseScans !== false) });
|
||||||
this.options.formatOut = formatOut;
|
this.options.formatOut = formatOut;
|
||||||
return this;
|
return this;
|
||||||
@ -732,7 +731,7 @@ Sharp.prototype.optimizeScans = Sharp.prototype.optimiseScans;
|
|||||||
Optionally provide an Object with attributes to update:
|
Optionally provide an Object with attributes to update:
|
||||||
orientation: numeric value for EXIF Orientation tag
|
orientation: numeric value for EXIF Orientation tag
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.withMetadata = function(withMetadata) {
|
Sharp.prototype.withMetadata = function (withMetadata) {
|
||||||
this.options.withMetadata = isBoolean(withMetadata) ? withMetadata : true;
|
this.options.withMetadata = isBoolean(withMetadata) ? withMetadata : true;
|
||||||
if (isObject(withMetadata)) {
|
if (isObject(withMetadata)) {
|
||||||
if (isDefined(withMetadata.orientation)) {
|
if (isDefined(withMetadata.orientation)) {
|
||||||
@ -749,7 +748,7 @@ Sharp.prototype.withMetadata = function(withMetadata) {
|
|||||||
/*
|
/*
|
||||||
Tile-based deep zoom output options: size, overlap, layout
|
Tile-based deep zoom output options: size, overlap, layout
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.tile = function(tile) {
|
Sharp.prototype.tile = function (tile) {
|
||||||
if (isObject(tile)) {
|
if (isObject(tile)) {
|
||||||
// Size of square tiles, in pixels
|
// Size of square tiles, in pixels
|
||||||
if (isDefined(tile.size)) {
|
if (isDefined(tile.size)) {
|
||||||
@ -793,7 +792,7 @@ Sharp.prototype.tile = function(tile) {
|
|||||||
/*
|
/*
|
||||||
Extend edges
|
Extend edges
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.extend = function(extend) {
|
Sharp.prototype.extend = function (extend) {
|
||||||
if (isInteger(extend) && extend > 0) {
|
if (isInteger(extend) && extend > 0) {
|
||||||
this.options.extendTop = extend;
|
this.options.extendTop = extend;
|
||||||
this.options.extendBottom = extend;
|
this.options.extendBottom = extend;
|
||||||
@ -854,7 +853,7 @@ module.exports.colorspace = module.exports.colourspace;
|
|||||||
options.kernel is the kernel to use for reductions, default 'lanczos3'
|
options.kernel is the kernel to use for reductions, default 'lanczos3'
|
||||||
options.interpolator is the interpolator to use for enlargements, default 'bicubic'
|
options.interpolator is the interpolator to use for enlargements, default 'bicubic'
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.resize = function(width, height, options) {
|
Sharp.prototype.resize = function (width, height, options) {
|
||||||
if (isDefined(width)) {
|
if (isDefined(width)) {
|
||||||
if (isInteger(width) && inRange(width, 1, maximum.width)) {
|
if (isInteger(width) && inRange(width, 1, maximum.width)) {
|
||||||
this.options.width = width;
|
this.options.width = width;
|
||||||
@ -899,11 +898,11 @@ Sharp.prototype.resize = function(width, height, options) {
|
|||||||
Assumes the image dimensions contained in the file header can be trusted.
|
Assumes the image dimensions contained in the file header can be trusted.
|
||||||
Alternatively can use boolean to disable or reset to default (maximum pixels)
|
Alternatively can use boolean to disable or reset to default (maximum pixels)
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.limitInputPixels = function(limit) {
|
Sharp.prototype.limitInputPixels = function (limit) {
|
||||||
//if we pass in false we represent the integer as 0 to disable
|
// if we pass in false we represent the integer as 0 to disable
|
||||||
if(limit === false) {
|
if (limit === false) {
|
||||||
limit = 0;
|
limit = 0;
|
||||||
} else if(limit === true) {
|
} else if (limit === true) {
|
||||||
limit = maximum.pixels;
|
limit = maximum.pixels;
|
||||||
}
|
}
|
||||||
if (typeof limit === 'number' && !Number.isNaN(limit) && limit % 1 === 0 && limit >= 0) {
|
if (typeof limit === 'number' && !Number.isNaN(limit) && limit % 1 === 0 && limit >= 0) {
|
||||||
@ -918,21 +917,21 @@ Sharp.prototype.limitInputPixels = function(limit) {
|
|||||||
* Write output image data to a file
|
* Write output image data to a file
|
||||||
* @throws {Error} if an attempt has been made to force Buffer/Stream output type
|
* @throws {Error} if an attempt has been made to force Buffer/Stream output type
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.toFile = function(fileOut, callback) {
|
Sharp.prototype.toFile = function (fileOut, callback) {
|
||||||
if (!fileOut || fileOut.length === 0) {
|
if (!fileOut || fileOut.length === 0) {
|
||||||
var errOutputInvalid = new Error('Invalid output');
|
const errOutputInvalid = new Error('Invalid output');
|
||||||
if (isFunction(callback)) {
|
if (isFunction(callback)) {
|
||||||
callback(errOutputInvalid);
|
callback(errOutputInvalid);
|
||||||
} else {
|
} else {
|
||||||
return BluebirdPromise.reject(errOutputInvalid);
|
return Promise.reject(errOutputInvalid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.options.input.file === fileOut) {
|
if (this.options.input.file === fileOut) {
|
||||||
var errOutputIsInput = new Error('Cannot use same file for input and output');
|
const errOutputIsInput = new Error('Cannot use same file for input and output');
|
||||||
if (isFunction(callback)) {
|
if (isFunction(callback)) {
|
||||||
callback(errOutputIsInput);
|
callback(errOutputIsInput);
|
||||||
} else {
|
} else {
|
||||||
return BluebirdPromise.reject(errOutputIsInput);
|
return Promise.reject(errOutputIsInput);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.options.fileOut = fileOut;
|
this.options.fileOut = fileOut;
|
||||||
@ -947,7 +946,7 @@ Sharp.prototype.toFile = function(fileOut, callback) {
|
|||||||
* @param {Function} [callback]
|
* @param {Function} [callback]
|
||||||
* @returns {Promise} when no callback is provided
|
* @returns {Promise} when no callback is provided
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.toBuffer = function(callback) {
|
Sharp.prototype.toBuffer = function (callback) {
|
||||||
return this._pipeline(callback);
|
return this._pipeline(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -960,7 +959,7 @@ Sharp.prototype.toBuffer = function(callback) {
|
|||||||
* @param {Boolean} [options.force=true] - force output format, otherwise attempt to use input format
|
* @param {Boolean} [options.force=true] - force output format, otherwise attempt to use input format
|
||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._updateFormatOut = function(formatOut, options) {
|
Sharp.prototype._updateFormatOut = function (formatOut, options) {
|
||||||
this.options.formatOut = (isObject(options) && options.force === false) ? 'input' : formatOut;
|
this.options.formatOut = (isObject(options) && options.force === false) ? 'input' : formatOut;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -972,7 +971,7 @@ Sharp.prototype._updateFormatOut = function(formatOut, options) {
|
|||||||
* @param {Boolean} val
|
* @param {Boolean} val
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._setBooleanOption = function(key, val) {
|
Sharp.prototype._setBooleanOption = function (key, val) {
|
||||||
if (isBoolean(val)) {
|
if (isBoolean(val)) {
|
||||||
this.options[key] = val;
|
this.options[key] = val;
|
||||||
} else {
|
} else {
|
||||||
@ -993,7 +992,7 @@ Sharp.prototype._setBooleanOption = function(key, val) {
|
|||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.jpeg = function(options) {
|
Sharp.prototype.jpeg = function (options) {
|
||||||
if (isObject(options)) {
|
if (isObject(options)) {
|
||||||
if (isDefined(options.quality)) {
|
if (isDefined(options.quality)) {
|
||||||
if (isInteger(options.quality) && inRange(options.quality, 1, 100)) {
|
if (isInteger(options.quality) && inRange(options.quality, 1, 100)) {
|
||||||
@ -1040,7 +1039,7 @@ Sharp.prototype.jpeg = function(options) {
|
|||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.png = function(options) {
|
Sharp.prototype.png = function (options) {
|
||||||
if (isObject(options)) {
|
if (isObject(options)) {
|
||||||
if (isDefined(options.progressive)) {
|
if (isDefined(options.progressive)) {
|
||||||
this._setBooleanOption('pngProgressive', options.progressive);
|
this._setBooleanOption('pngProgressive', options.progressive);
|
||||||
@ -1067,7 +1066,7 @@ Sharp.prototype.png = function(options) {
|
|||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.webp = function(options) {
|
Sharp.prototype.webp = function (options) {
|
||||||
if (isObject(options)) {
|
if (isObject(options)) {
|
||||||
if (isDefined(options.quality)) {
|
if (isDefined(options.quality)) {
|
||||||
if (isInteger(options.quality) && inRange(options.quality, 1, 100)) {
|
if (isInteger(options.quality) && inRange(options.quality, 1, 100)) {
|
||||||
@ -1088,7 +1087,7 @@ Sharp.prototype.webp = function(options) {
|
|||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.tiff = function(options) {
|
Sharp.prototype.tiff = function (options) {
|
||||||
if (isObject(options)) {
|
if (isObject(options)) {
|
||||||
if (isDefined(options.quality)) {
|
if (isDefined(options.quality)) {
|
||||||
if (isInteger(options.quality) && inRange(options.quality, 1, 100)) {
|
if (isInteger(options.quality) && inRange(options.quality, 1, 100)) {
|
||||||
@ -1105,7 +1104,7 @@ Sharp.prototype.tiff = function(options) {
|
|||||||
* Force output to be raw, uncompressed uint8 pixel data.
|
* Force output to be raw, uncompressed uint8 pixel data.
|
||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.raw = function() {
|
Sharp.prototype.raw = function () {
|
||||||
return this._updateFormatOut('raw');
|
return this._updateFormatOut('raw');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1116,7 +1115,7 @@ Sharp.prototype.raw = function() {
|
|||||||
* @returns {Object} this
|
* @returns {Object} this
|
||||||
* @throws {Error} unsupported format or options
|
* @throws {Error} unsupported format or options
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.toFormat = function(format, options) {
|
Sharp.prototype.toFormat = function (format, options) {
|
||||||
if (isObject(format) && isString(format.id)) {
|
if (isObject(format) && isString(format.id)) {
|
||||||
format = format.id;
|
format = format.id;
|
||||||
}
|
}
|
||||||
@ -1129,7 +1128,7 @@ Sharp.prototype.toFormat = function(format, options) {
|
|||||||
/*
|
/*
|
||||||
Used by a Writable Stream to notify that it is ready for data
|
Used by a Writable Stream to notify that it is ready for data
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._read = function() {
|
Sharp.prototype._read = function () {
|
||||||
if (!this.options.streamOut) {
|
if (!this.options.streamOut) {
|
||||||
this.options.streamOut = true;
|
this.options.streamOut = true;
|
||||||
this._pipeline();
|
this._pipeline();
|
||||||
@ -1140,13 +1139,13 @@ Sharp.prototype._read = function() {
|
|||||||
Invoke the C++ image processing pipeline
|
Invoke the C++ image processing pipeline
|
||||||
Supports callback, stream and promise variants
|
Supports callback, stream and promise variants
|
||||||
*/
|
*/
|
||||||
Sharp.prototype._pipeline = function(callback) {
|
Sharp.prototype._pipeline = function (callback) {
|
||||||
var that = this;
|
const that = this;
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
// output=file/buffer
|
// output=file/buffer
|
||||||
if (this._isStreamInput()) {
|
if (this._isStreamInput()) {
|
||||||
// output=file/buffer, input=stream
|
// output=file/buffer, input=stream
|
||||||
this.on('finish', function() {
|
this.on('finish', function () {
|
||||||
that._flattenBufferIn();
|
that._flattenBufferIn();
|
||||||
sharp.pipeline(that.options, callback);
|
sharp.pipeline(that.options, callback);
|
||||||
});
|
});
|
||||||
@ -1159,9 +1158,9 @@ Sharp.prototype._pipeline = function(callback) {
|
|||||||
// output=stream
|
// output=stream
|
||||||
if (this._isStreamInput()) {
|
if (this._isStreamInput()) {
|
||||||
// output=stream, input=stream
|
// output=stream, input=stream
|
||||||
this.on('finish', function() {
|
this.on('finish', function () {
|
||||||
that._flattenBufferIn();
|
that._flattenBufferIn();
|
||||||
sharp.pipeline(that.options, function(err, data, info) {
|
sharp.pipeline(that.options, function (err, data, info) {
|
||||||
if (err) {
|
if (err) {
|
||||||
that.emit('error', err);
|
that.emit('error', err);
|
||||||
} else {
|
} else {
|
||||||
@ -1173,7 +1172,7 @@ Sharp.prototype._pipeline = function(callback) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// output=stream, input=file/buffer
|
// output=stream, input=file/buffer
|
||||||
sharp.pipeline(this.options, function(err, data, info) {
|
sharp.pipeline(this.options, function (err, data, info) {
|
||||||
if (err) {
|
if (err) {
|
||||||
that.emit('error', err);
|
that.emit('error', err);
|
||||||
} else {
|
} else {
|
||||||
@ -1188,10 +1187,10 @@ Sharp.prototype._pipeline = function(callback) {
|
|||||||
// output=promise
|
// output=promise
|
||||||
if (this._isStreamInput()) {
|
if (this._isStreamInput()) {
|
||||||
// output=promise, input=stream
|
// output=promise, input=stream
|
||||||
return new BluebirdPromise(function(resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
that.on('finish', function() {
|
that.on('finish', function () {
|
||||||
that._flattenBufferIn();
|
that._flattenBufferIn();
|
||||||
sharp.pipeline(that.options, function(err, data) {
|
sharp.pipeline(that.options, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
@ -1202,8 +1201,8 @@ Sharp.prototype._pipeline = function(callback) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// output=promise, input=file/buffer
|
// output=promise, input=file/buffer
|
||||||
return new BluebirdPromise(function(resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
sharp.pipeline(that.options, function(err, data) {
|
sharp.pipeline(that.options, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
@ -1219,11 +1218,11 @@ Sharp.prototype._pipeline = function(callback) {
|
|||||||
Reads the image header and returns metadata
|
Reads the image header and returns metadata
|
||||||
Supports callback, stream and promise variants
|
Supports callback, stream and promise variants
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.metadata = function(callback) {
|
Sharp.prototype.metadata = function (callback) {
|
||||||
var that = this;
|
const that = this;
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
if (this._isStreamInput()) {
|
if (this._isStreamInput()) {
|
||||||
this.on('finish', function() {
|
this.on('finish', function () {
|
||||||
that._flattenBufferIn();
|
that._flattenBufferIn();
|
||||||
sharp.metadata(that.options, callback);
|
sharp.metadata(that.options, callback);
|
||||||
});
|
});
|
||||||
@ -1233,10 +1232,10 @@ Sharp.prototype.metadata = function(callback) {
|
|||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
if (this._isStreamInput()) {
|
if (this._isStreamInput()) {
|
||||||
return new BluebirdPromise(function(resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
that.on('finish', function() {
|
that.on('finish', function () {
|
||||||
that._flattenBufferIn();
|
that._flattenBufferIn();
|
||||||
sharp.metadata(that.options, function(err, metadata) {
|
sharp.metadata(that.options, function (err, metadata) {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
@ -1246,8 +1245,8 @@ Sharp.prototype.metadata = function(callback) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return new BluebirdPromise(function(resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
sharp.metadata(that.options, function(err, metadata) {
|
sharp.metadata(that.options, function (err, metadata) {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
@ -1263,13 +1262,13 @@ Sharp.prototype.metadata = function(callback) {
|
|||||||
Clone new instance using existing options.
|
Clone new instance using existing options.
|
||||||
Cloned instances share the same input.
|
Cloned instances share the same input.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.clone = function() {
|
Sharp.prototype.clone = function () {
|
||||||
var that = this;
|
const that = this;
|
||||||
// Clone existing options
|
// Clone existing options
|
||||||
var clone = new Sharp();
|
const clone = new Sharp();
|
||||||
util._extend(clone.options, this.options);
|
util._extend(clone.options, this.options);
|
||||||
// Pass 'finish' event to clone for Stream-based input
|
// Pass 'finish' event to clone for Stream-based input
|
||||||
this.on('finish', function() {
|
this.on('finish', function () {
|
||||||
// Clone inherits input data
|
// Clone inherits input data
|
||||||
that._flattenBufferIn();
|
that._flattenBufferIn();
|
||||||
clone.options.bufferIn = that.options.bufferIn;
|
clone.options.bufferIn = that.options.bufferIn;
|
||||||
@ -1281,7 +1280,7 @@ Sharp.prototype.clone = function() {
|
|||||||
/**
|
/**
|
||||||
Get and set cache memory, file and item limits
|
Get and set cache memory, file and item limits
|
||||||
*/
|
*/
|
||||||
module.exports.cache = function(options) {
|
module.exports.cache = function (options) {
|
||||||
if (isBoolean(options)) {
|
if (isBoolean(options)) {
|
||||||
if (options) {
|
if (options) {
|
||||||
// Default cache settings of 50MB, 20 files, 100 items
|
// Default cache settings of 50MB, 20 files, 100 items
|
||||||
@ -1301,21 +1300,21 @@ module.exports.cache(true);
|
|||||||
/*
|
/*
|
||||||
Get and set size of thread pool
|
Get and set size of thread pool
|
||||||
*/
|
*/
|
||||||
module.exports.concurrency = function(concurrency) {
|
module.exports.concurrency = function (concurrency) {
|
||||||
return sharp.concurrency(isInteger(concurrency) ? concurrency : null);
|
return sharp.concurrency(isInteger(concurrency) ? concurrency : null);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get internal counters
|
Get internal counters
|
||||||
*/
|
*/
|
||||||
module.exports.counters = function() {
|
module.exports.counters = function () {
|
||||||
return sharp.counters();
|
return sharp.counters();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get and set use of SIMD vector unit instructions
|
Get and set use of SIMD vector unit instructions
|
||||||
*/
|
*/
|
||||||
module.exports.simd = function(simd) {
|
module.exports.simd = function (simd) {
|
||||||
return sharp.simd(isBoolean(simd) ? simd : null);
|
return sharp.simd(isBoolean(simd) ? simd : null);
|
||||||
};
|
};
|
||||||
// Switch off default
|
// Switch off default
|
||||||
|
28
package.json
28
package.json
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||||
"version": "0.17.0",
|
"version": "0.17.0",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@ -29,14 +30,11 @@
|
|||||||
"Matt Hirsch <mhirsch@media.mit.edu>",
|
"Matt Hirsch <mhirsch@media.mit.edu>",
|
||||||
"Matthias Thoemmes <thoemmes@gmail.com>"
|
"Matthias Thoemmes <thoemmes@gmail.com>"
|
||||||
],
|
],
|
||||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf node_modules/ build/ include/ lib/ coverage/ test/fixtures/output.*",
|
"clean": "rm -rf node_modules/ build/ include/ lib/ coverage/ test/fixtures/output.*",
|
||||||
"test": "VIPS_WARNING=0 node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- --slow=5000 --timeout=30000 ./test/unit/*.js",
|
"test": "semistandard && cross-env VIPS_WARNING=0 nyc --reporter=lcov --branches=96 mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
|
||||||
"test-win": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
|
|
||||||
"test-leak": "./test/leak/leak.sh",
|
"test-leak": "./test/leak/leak.sh",
|
||||||
"test-packaging": "./packaging/test-linux-x64.sh",
|
"test-packaging": "./packaging/test-linux-x64.sh"
|
||||||
"test-clean": "rm -rf coverage/ test/fixtures/output.* && npm install && npm test"
|
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -59,24 +57,24 @@
|
|||||||
"vips"
|
"vips"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bluebird": "^3.4.6",
|
"caw": "^2.0.0",
|
||||||
"color": "^0.11.3",
|
"color": "^0.11.3",
|
||||||
|
"got": "^6.5.0",
|
||||||
"nan": "^2.4.0",
|
"nan": "^2.4.0",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.3.0",
|
||||||
"request": "^2.75.0",
|
|
||||||
"tar": "^2.2.1"
|
"tar": "^2.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"async": "^2.1.2",
|
"async": "^2.1.2",
|
||||||
"bufferutil": "^1.2.1",
|
"bufferutil": "^1.2.1",
|
||||||
"coveralls": "^2.11.14",
|
"cross-env": "^3.1.3",
|
||||||
"exif-reader": "^1.0.1",
|
"exif-reader": "^1.0.1",
|
||||||
"icc": "^0.0.2",
|
"icc": "^0.0.2",
|
||||||
"istanbul": "^0.4.5",
|
|
||||||
"mocha": "^3.1.2",
|
"mocha": "^3.1.2",
|
||||||
"mocha-jshint": "^2.3.1",
|
|
||||||
"node-cpplint": "^0.4.0",
|
"node-cpplint": "^0.4.0",
|
||||||
|
"nyc": "^8.3.2",
|
||||||
"rimraf": "^2.5.4",
|
"rimraf": "^2.5.4",
|
||||||
|
"semistandard": "^9.1.0",
|
||||||
"unzip": "^0.1.11"
|
"unzip": "^0.1.11"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@ -84,6 +82,14 @@
|
|||||||
"libvips": "8.4.2"
|
"libvips": "8.4.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10"
|
"node": ">=4"
|
||||||
|
},
|
||||||
|
"semistandard": {
|
||||||
|
"env": [
|
||||||
|
"mocha"
|
||||||
|
],
|
||||||
|
"ignore": [
|
||||||
|
"test"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
test/fixtures/index.js
vendored
40
test/fixtures/index.js
vendored
@ -1,34 +1,32 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
const path = require('path');
|
||||||
var assert = require('assert');
|
const sharp = require('../../index');
|
||||||
var sharp = require('../../index');
|
const maxColourDistance = require('../../build/Release/sharp')._maxColourDistance;
|
||||||
var maxColourDistance = require('../../build/Release/sharp')._maxColourDistance;
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
var getPath = function(filename) {
|
const getPath = function (filename) {
|
||||||
return path.join(__dirname, filename);
|
return path.join(__dirname, filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generates a 64-bit-as-binary-string image fingerprint
|
// Generates a 64-bit-as-binary-string image fingerprint
|
||||||
// Based on the dHash gradient method - see http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
|
// Based on the dHash gradient method - see http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
|
||||||
var fingerprint = function(image, callback) {
|
const fingerprint = function (image, callback) {
|
||||||
sharp(image)
|
sharp(image)
|
||||||
.greyscale()
|
.greyscale()
|
||||||
.normalise()
|
.normalise()
|
||||||
.resize(9, 8)
|
.resize(9, 8)
|
||||||
.ignoreAspectRatio()
|
.ignoreAspectRatio()
|
||||||
.raw()
|
.raw()
|
||||||
.toBuffer(function(err, data) {
|
.toBuffer(function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
var fingerprint = '';
|
let fingerprint = '';
|
||||||
for (var col = 0; col < 8; col++) {
|
for (let col = 0; col < 8; col++) {
|
||||||
var gradient = 0;
|
for (let row = 0; row < 8; row++) {
|
||||||
for (var row = 0; row < 8; row++) {
|
const left = data[row * 8 + col];
|
||||||
var left = data[row * 8 + col];
|
const right = data[row * 8 + col + 1];
|
||||||
var right = data[row * 8 + col + 1];
|
|
||||||
fingerprint = fingerprint + (left < right ? '1' : '0');
|
fingerprint = fingerprint + (left < right ? '1' : '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,14 +107,14 @@ module.exports = {
|
|||||||
path: getPath,
|
path: getPath,
|
||||||
|
|
||||||
// Path for expected output images
|
// Path for expected output images
|
||||||
expected: function(filename) {
|
expected: function (filename) {
|
||||||
return getPath(path.join('expected', filename));
|
return getPath(path.join('expected', filename));
|
||||||
},
|
},
|
||||||
|
|
||||||
// Verify similarity of expected vs actual images via fingerprint
|
// Verify similarity of expected vs actual images via fingerprint
|
||||||
// Specify distance threshold using `options={threshold: 42}`, default
|
// Specify distance threshold using `options={threshold: 42}`, default
|
||||||
// `threshold` is 5;
|
// `threshold` is 5;
|
||||||
assertSimilar: function(expectedImage, actualImage, options, callback) {
|
assertSimilar: function (expectedImage, actualImage, options, callback) {
|
||||||
if (typeof options === 'function') {
|
if (typeof options === 'function') {
|
||||||
callback = options;
|
callback = options;
|
||||||
options = {};
|
options = {};
|
||||||
@ -138,12 +136,12 @@ module.exports = {
|
|||||||
throw new TypeError('`callback` must be a function');
|
throw new TypeError('`callback` must be a function');
|
||||||
}
|
}
|
||||||
|
|
||||||
fingerprint(expectedImage, function(err, expectedFingerprint) {
|
fingerprint(expectedImage, function (err, expectedFingerprint) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
fingerprint(actualImage, function(err, actualFingerprint) {
|
fingerprint(actualImage, function (err, actualFingerprint) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
var distance = 0;
|
let distance = 0;
|
||||||
for (var i = 0; i < 64; i++) {
|
for (let i = 0; i < 64; i++) {
|
||||||
if (expectedFingerprint[i] !== actualFingerprint[i]) {
|
if (expectedFingerprint[i] !== actualFingerprint[i]) {
|
||||||
distance++;
|
distance++;
|
||||||
}
|
}
|
||||||
@ -158,7 +156,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
assertMaxColourDistance: function(actualImagePath, expectedImagePath, acceptedDistance) {
|
assertMaxColourDistance: function (actualImagePath, expectedImagePath, acceptedDistance) {
|
||||||
if (typeof actualImagePath !== 'string') {
|
if (typeof actualImagePath !== 'string') {
|
||||||
throw new TypeError('`actualImagePath` must be a string; got ' + actualImagePath);
|
throw new TypeError('`actualImagePath` must be a string; got ' + actualImagePath);
|
||||||
}
|
}
|
||||||
@ -169,7 +167,7 @@ module.exports = {
|
|||||||
// Default threshold
|
// Default threshold
|
||||||
acceptedDistance = 1;
|
acceptedDistance = 1;
|
||||||
}
|
}
|
||||||
var distance = maxColourDistance(actualImagePath, expectedImagePath);
|
const distance = maxColourDistance(actualImagePath, expectedImagePath);
|
||||||
if (distance > acceptedDistance) {
|
if (distance > acceptedDistance) {
|
||||||
throw new Error('Expected maximum absolute distance of ' + acceptedDistance + ', actual ' + distance);
|
throw new Error('Expected maximum absolute distance of ' + acceptedDistance + ', actual ' + distance);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var assert = require('assert');
|
const assert = require('assert');
|
||||||
var fs = require('fs');
|
const fs = require('fs');
|
||||||
var sharp = require('../../index');
|
|
||||||
var fixtures = require('../fixtures');
|
|
||||||
var BluebirdPromise = require('bluebird');
|
|
||||||
|
|
||||||
describe('Image channel insertion', function() {
|
const sharp = require('../../index');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
it('Grayscale to RGB, buffer', function(done) {
|
describe('Image channel insertion', function () {
|
||||||
|
it('Grayscale to RGB, buffer', function (done) {
|
||||||
sharp(fixtures.inputPng) // gray -> red
|
sharp(fixtures.inputPng) // gray -> red
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel(fixtures.inputPngTestJoinChannel) // new green channel
|
.joinChannel(fixtures.inputPngTestJoinChannel) // new green channel
|
||||||
.joinChannel(fixtures.inputPngStripesH) // new blue channel
|
.joinChannel(fixtures.inputPngStripesH) // new blue channel
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -22,12 +21,12 @@ describe('Image channel insertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Grayscale to RGB, file', function(done) {
|
it('Grayscale to RGB, file', function (done) {
|
||||||
sharp(fixtures.inputPng) // gray -> red
|
sharp(fixtures.inputPng) // gray -> red
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel(fs.readFileSync(fixtures.inputPngTestJoinChannel)) // new green channel
|
.joinChannel(fs.readFileSync(fixtures.inputPngTestJoinChannel)) // new green channel
|
||||||
.joinChannel(fs.readFileSync(fixtures.inputPngStripesH)) // new blue channel
|
.joinChannel(fs.readFileSync(fixtures.inputPngStripesH)) // new blue channel
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -36,14 +35,14 @@ describe('Image channel insertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Grayscale to RGBA, buffer', function(done) {
|
it('Grayscale to RGBA, buffer', function (done) {
|
||||||
sharp(fixtures.inputPng) // gray -> red
|
sharp(fixtures.inputPng) // gray -> red
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel([fixtures.inputPngTestJoinChannel,
|
.joinChannel([fixtures.inputPngTestJoinChannel,
|
||||||
fixtures.inputPngStripesH,
|
fixtures.inputPngStripesH,
|
||||||
fixtures.inputPngStripesV]) // new green + blue + alpha channel
|
fixtures.inputPngStripesV]) // new green + blue + alpha channel
|
||||||
.toColourspace(sharp.colourspace.srgb)
|
.toColourspace(sharp.colourspace.srgb)
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -52,14 +51,14 @@ describe('Image channel insertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Grayscale to RGBA, file', function(done) {
|
it('Grayscale to RGBA, file', function (done) {
|
||||||
sharp(fixtures.inputPng) // gray -> red
|
sharp(fixtures.inputPng) // gray -> red
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel([fs.readFileSync(fixtures.inputPngTestJoinChannel), // new green channel
|
.joinChannel([fs.readFileSync(fixtures.inputPngTestJoinChannel), // new green channel
|
||||||
fs.readFileSync(fixtures.inputPngStripesH), // new blue channel
|
fs.readFileSync(fixtures.inputPngStripesH), // new blue channel
|
||||||
fs.readFileSync(fixtures.inputPngStripesV)]) // new alpha channel
|
fs.readFileSync(fixtures.inputPngStripesV)]) // new alpha channel
|
||||||
.toColourspace('srgb')
|
.toColourspace('srgb')
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -68,7 +67,7 @@ describe('Image channel insertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Grayscale to CMYK, buffers', function(done) {
|
it('Grayscale to CMYK, buffers', function (done) {
|
||||||
sharp(fixtures.inputPng) // gray -> magenta
|
sharp(fixtures.inputPng) // gray -> magenta
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel([fs.readFileSync(fixtures.inputPngTestJoinChannel), // new cyan channel
|
.joinChannel([fs.readFileSync(fixtures.inputPngTestJoinChannel), // new cyan channel
|
||||||
@ -76,7 +75,7 @@ describe('Image channel insertion', function() {
|
|||||||
fs.readFileSync(fixtures.inputPngStripesV)]) // new black channel
|
fs.readFileSync(fixtures.inputPngStripesV)]) // new black channel
|
||||||
.toColorspace('cmyk')
|
.toColorspace('cmyk')
|
||||||
.toFormat('jpeg')
|
.toFormat('jpeg')
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -85,12 +84,12 @@ describe('Image channel insertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Join raw buffers to RGB', function(done) {
|
it('Join raw buffers to RGB', function (done) {
|
||||||
BluebirdPromise.all([
|
Promise.all([
|
||||||
sharp(fixtures.inputPngTestJoinChannel).toColourspace('b-w').raw().toBuffer(),
|
sharp(fixtures.inputPngTestJoinChannel).toColourspace('b-w').raw().toBuffer(),
|
||||||
sharp(fixtures.inputPngStripesH).toColourspace('b-w').raw().toBuffer()
|
sharp(fixtures.inputPngStripesH).toColourspace('b-w').raw().toBuffer()
|
||||||
])
|
])
|
||||||
.then(function(buffers) {
|
.then(function (buffers) {
|
||||||
sharp(fixtures.inputPng)
|
sharp(fixtures.inputPng)
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel(buffers,
|
.joinChannel(buffers,
|
||||||
@ -99,7 +98,7 @@ describe('Image channel insertion', function() {
|
|||||||
height: 240,
|
height: 240,
|
||||||
channels: 1
|
channels: 1
|
||||||
}})
|
}})
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -107,19 +106,19 @@ describe('Image channel insertion', function() {
|
|||||||
fixtures.assertSimilar(fixtures.expected('joinChannel-rgb.jpg'), data, done);
|
fixtures.assertSimilar(fixtures.expected('joinChannel-rgb.jpg'), data, done);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function (err) {
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Grayscale to RGBA, files, two arrays', function(done) {
|
it('Grayscale to RGBA, files, two arrays', function (done) {
|
||||||
sharp(fixtures.inputPng) // gray -> red
|
sharp(fixtures.inputPng) // gray -> red
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.joinChannel([fs.readFileSync(fixtures.inputPngTestJoinChannel)]) // new green channel
|
.joinChannel([fs.readFileSync(fixtures.inputPngTestJoinChannel)]) // new green channel
|
||||||
.joinChannel([fs.readFileSync(fixtures.inputPngStripesH), // new blue channel
|
.joinChannel([fs.readFileSync(fixtures.inputPngStripesH), // new blue channel
|
||||||
fs.readFileSync(fixtures.inputPngStripesV)]) // new alpha channel
|
fs.readFileSync(fixtures.inputPngStripesV)]) // new alpha channel
|
||||||
.toColourspace('srgb')
|
.toColourspace('srgb')
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -128,24 +127,23 @@ describe('Image channel insertion', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Invalid raw buffer description', function() {
|
it('Invalid raw buffer description', function () {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().joinChannel(fs.readFileSync(fixtures.inputPng),{raw:{}});
|
sharp().joinChannel(fs.readFileSync(fixtures.inputPng), {raw: {}});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Invalid input', function() {
|
it('Invalid input', function () {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.joinChannel(1);
|
.joinChannel(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No arguments', function() {
|
it('No arguments', function () {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.joinChannel();
|
.joinChannel();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1 +0,0 @@
|
|||||||
require('mocha-jshint')();
|
|
@ -1,35 +1,35 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var fs = require('fs');
|
const fs = require('fs');
|
||||||
var path = require('path');
|
const path = require('path');
|
||||||
var assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
var async = require('async');
|
const eachLimit = require('async/eachLimit');
|
||||||
var rimraf = require('rimraf');
|
const rimraf = require('rimraf');
|
||||||
var unzip = require('unzip');
|
const unzip = require('unzip');
|
||||||
|
|
||||||
var sharp = require('../../index');
|
const sharp = require('../../index');
|
||||||
var fixtures = require('../fixtures');
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
// Verifies all tiles in a given dz output directory are <= size
|
// Verifies all tiles in a given dz output directory are <= size
|
||||||
var assertDeepZoomTiles = function(directory, expectedSize, expectedLevels, done) {
|
const assertDeepZoomTiles = function (directory, expectedSize, expectedLevels, done) {
|
||||||
// Get levels
|
// Get levels
|
||||||
var levels = fs.readdirSync(directory);
|
const levels = fs.readdirSync(directory);
|
||||||
assert.strictEqual(expectedLevels, levels.length);
|
assert.strictEqual(expectedLevels, levels.length);
|
||||||
// Get tiles
|
// Get tiles
|
||||||
var tiles = [];
|
const tiles = [];
|
||||||
levels.forEach(function(level) {
|
levels.forEach(function (level) {
|
||||||
// Verify level directory name
|
// Verify level directory name
|
||||||
assert.strictEqual(true, /^[0-9]+$/.test(level));
|
assert.strictEqual(true, /^[0-9]+$/.test(level));
|
||||||
fs.readdirSync(path.join(directory, level)).forEach(function(tile) {
|
fs.readdirSync(path.join(directory, level)).forEach(function (tile) {
|
||||||
// Verify tile file name
|
// Verify tile file name
|
||||||
assert.strictEqual(true, /^[0-9]+_[0-9]+\.jpeg$/.test(tile));
|
assert.strictEqual(true, /^[0-9]+_[0-9]+\.jpeg$/.test(tile));
|
||||||
tiles.push(path.join(directory, level, tile));
|
tiles.push(path.join(directory, level, tile));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Verify each tile is <= expectedSize
|
// Verify each tile is <= expectedSize
|
||||||
async.eachSeries(tiles, function(tile, done) {
|
eachLimit(tiles, 8, function (tile, done) {
|
||||||
sharp(tile).metadata(function(err, metadata) {
|
sharp(tile).metadata(function (err, metadata) {
|
||||||
if (err) {
|
if (err) {
|
||||||
done(err);
|
done(err);
|
||||||
} else {
|
} else {
|
||||||
@ -46,11 +46,10 @@ var assertDeepZoomTiles = function(directory, expectedSize, expectedLevels, done
|
|||||||
}, done);
|
}, done);
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Tile', function() {
|
describe('Tile', function () {
|
||||||
|
it('Valid size values pass', function () {
|
||||||
it('Valid size values pass', function() {
|
[1, 8192].forEach(function (size) {
|
||||||
[1, 8192].forEach(function(size) {
|
assert.doesNotThrow(function () {
|
||||||
assert.doesNotThrow(function() {
|
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
size: size
|
size: size
|
||||||
});
|
});
|
||||||
@ -58,9 +57,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Invalid size values fail', function() {
|
it('Invalid size values fail', function () {
|
||||||
['zoinks', 1.1, -1, 0, 8193].forEach(function(size) {
|
['zoinks', 1.1, -1, 0, 8193].forEach(function (size) {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
size: size
|
size: size
|
||||||
});
|
});
|
||||||
@ -68,9 +67,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Valid overlap values pass', function() {
|
it('Valid overlap values pass', function () {
|
||||||
[0, 8192].forEach(function(overlap) {
|
[0, 8192].forEach(function (overlap) {
|
||||||
assert.doesNotThrow(function() {
|
assert.doesNotThrow(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
size: 8192,
|
size: 8192,
|
||||||
overlap: overlap
|
overlap: overlap
|
||||||
@ -79,9 +78,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Invalid overlap values fail', function() {
|
it('Invalid overlap values fail', function () {
|
||||||
['zoinks', 1.1, -1, 8193].forEach(function(overlap) {
|
['zoinks', 1.1, -1, 8193].forEach(function (overlap) {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
overlap: overlap
|
overlap: overlap
|
||||||
});
|
});
|
||||||
@ -89,9 +88,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Valid container values pass', function() {
|
it('Valid container values pass', function () {
|
||||||
['fs', 'zip'].forEach(function(container) {
|
['fs', 'zip'].forEach(function (container) {
|
||||||
assert.doesNotThrow(function() {
|
assert.doesNotThrow(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
container: container
|
container: container
|
||||||
});
|
});
|
||||||
@ -99,9 +98,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Invalid container values fail', function() {
|
it('Invalid container values fail', function () {
|
||||||
['zoinks', 1].forEach(function(container) {
|
['zoinks', 1].forEach(function (container) {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
container: container
|
container: container
|
||||||
});
|
});
|
||||||
@ -109,9 +108,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Valid layout values pass', function() {
|
it('Valid layout values pass', function () {
|
||||||
['dz', 'google', 'zoomify'].forEach(function(layout) {
|
['dz', 'google', 'zoomify'].forEach(function (layout) {
|
||||||
assert.doesNotThrow(function() {
|
assert.doesNotThrow(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
layout: layout
|
layout: layout
|
||||||
});
|
});
|
||||||
@ -119,9 +118,9 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Invalid layout values fail', function() {
|
it('Invalid layout values fail', function () {
|
||||||
['zoinks', 1].forEach(function(layout) {
|
['zoinks', 1].forEach(function (layout) {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().tile({
|
sharp().tile({
|
||||||
layout: layout
|
layout: layout
|
||||||
});
|
});
|
||||||
@ -129,25 +128,24 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Prevent larger overlap than default size', function() {
|
it('Prevent larger overlap than default size', function () {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().tile({overlap: 257});
|
sharp().tile({overlap: 257});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Prevent larger overlap than provided size', function() {
|
it('Prevent larger overlap than provided size', function () {
|
||||||
assert.throws(function() {
|
assert.throws(function () {
|
||||||
sharp().tile({size: 512, overlap: 513});
|
sharp().tile({size: 512, overlap: 513});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (sharp.format.dz.output.file) {
|
if (sharp.format.dz.output.file) {
|
||||||
|
it('Deep Zoom layout', function (done) {
|
||||||
it('Deep Zoom layout', function(done) {
|
const directory = fixtures.path('output.dzi_files');
|
||||||
var directory = fixtures.path('output.dzi_files');
|
rimraf(directory, function () {
|
||||||
rimraf(directory, function() {
|
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.toFile(fixtures.path('output.dzi'), function(err, info) {
|
.toFile(fixtures.path('output.dzi'), function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('dz', info.format);
|
assert.strictEqual('dz', info.format);
|
||||||
assertDeepZoomTiles(directory, 256, 13, done);
|
assertDeepZoomTiles(directory, 256, 13, done);
|
||||||
@ -155,15 +153,15 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Deep Zoom layout with custom size+overlap', function(done) {
|
it('Deep Zoom layout with custom size+overlap', function (done) {
|
||||||
var directory = fixtures.path('output.512.dzi_files');
|
const directory = fixtures.path('output.512.dzi_files');
|
||||||
rimraf(directory, function() {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.tile({
|
.tile({
|
||||||
size: 512,
|
size: 512,
|
||||||
overlap: 16
|
overlap: 16
|
||||||
})
|
})
|
||||||
.toFile(fixtures.path('output.512.dzi'), function(err, info) {
|
.toFile(fixtures.path('output.512.dzi'), function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('dz', info.format);
|
assert.strictEqual('dz', info.format);
|
||||||
assertDeepZoomTiles(directory, 512 + 2 * 16, 13, done);
|
assertDeepZoomTiles(directory, 512 + 2 * 16, 13, done);
|
||||||
@ -171,17 +169,17 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Zoomify layout', function(done) {
|
it('Zoomify layout', function (done) {
|
||||||
var directory = fixtures.path('output.zoomify.dzi');
|
const directory = fixtures.path('output.zoomify.dzi');
|
||||||
rimraf(directory, function() {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.tile({
|
.tile({
|
||||||
layout: 'zoomify'
|
layout: 'zoomify'
|
||||||
})
|
})
|
||||||
.toFile(fixtures.path('output.zoomify.dzi'), function(err, info) {
|
.toFile(fixtures.path('output.zoomify.dzi'), function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('dz', info.format);
|
assert.strictEqual('dz', info.format);
|
||||||
fs.stat(path.join(directory, 'ImageProperties.xml'), function(err, stat) {
|
fs.stat(path.join(directory, 'ImageProperties.xml'), function (err, stat) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, stat.isFile());
|
assert.strictEqual(true, stat.isFile());
|
||||||
assert.strictEqual(true, stat.size > 0);
|
assert.strictEqual(true, stat.size > 0);
|
||||||
@ -191,17 +189,17 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Google layout', function(done) {
|
it('Google layout', function (done) {
|
||||||
var directory = fixtures.path('output.google.dzi');
|
const directory = fixtures.path('output.google.dzi');
|
||||||
rimraf(directory, function() {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.tile({
|
.tile({
|
||||||
layout: 'google'
|
layout: 'google'
|
||||||
})
|
})
|
||||||
.toFile(directory, function(err, info) {
|
.toFile(directory, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('dz', info.format);
|
assert.strictEqual('dz', info.format);
|
||||||
fs.stat(path.join(directory, '0', '0', '0.jpg'), function(err, stat) {
|
fs.stat(path.join(directory, '0', '0', '0.jpg'), function (err, stat) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, stat.isFile());
|
assert.strictEqual(true, stat.isFile());
|
||||||
assert.strictEqual(true, stat.size > 0);
|
assert.strictEqual(true, stat.size > 0);
|
||||||
@ -211,23 +209,23 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Write to ZIP container using file extension', function(done) {
|
it('Write to ZIP container using file extension', function (done) {
|
||||||
var container = fixtures.path('output.dz.container.zip');
|
const container = fixtures.path('output.dz.container.zip');
|
||||||
var extractTo = fixtures.path('output.dz.container');
|
const extractTo = fixtures.path('output.dz.container');
|
||||||
var directory = path.join(extractTo, 'output.dz.container_files');
|
const directory = path.join(extractTo, 'output.dz.container_files');
|
||||||
rimraf(directory, function() {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.toFile(container, function(err, info) {
|
.toFile(container, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('dz', info.format);
|
assert.strictEqual('dz', info.format);
|
||||||
fs.stat(container, function(err, stat) {
|
fs.stat(container, function (err, stat) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, stat.isFile());
|
assert.strictEqual(true, stat.isFile());
|
||||||
assert.strictEqual(true, stat.size > 0);
|
assert.strictEqual(true, stat.size > 0);
|
||||||
fs.createReadStream(container)
|
fs.createReadStream(container)
|
||||||
.pipe(unzip.Extract({path: path.dirname(extractTo)}))
|
.pipe(unzip.Extract({path: path.dirname(extractTo)}))
|
||||||
.on('error', function(err) { throw err; })
|
.on('error', function (err) { throw err; })
|
||||||
.on('close', function() {
|
.on('close', function () {
|
||||||
assertDeepZoomTiles(directory, 256, 13, done);
|
assertDeepZoomTiles(directory, 256, 13, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -235,34 +233,32 @@ describe('Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Write to ZIP container using container tile option', function(done) {
|
it('Write to ZIP container using container tile option', function (done) {
|
||||||
var container = fixtures.path('output.dz.containeropt.zip');
|
const container = fixtures.path('output.dz.containeropt.zip');
|
||||||
var extractTo = fixtures.path('output.dz.containeropt');
|
const extractTo = fixtures.path('output.dz.containeropt');
|
||||||
var directory = path.join(extractTo, 'output.dz.containeropt_files');
|
const directory = path.join(extractTo, 'output.dz.containeropt_files');
|
||||||
rimraf(directory, function() {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.tile({
|
.tile({
|
||||||
container: 'zip'
|
container: 'zip'
|
||||||
})
|
})
|
||||||
.toFile(container, function(err, info) {
|
.toFile(container, function (err, info) {
|
||||||
// Vips overrides .dzi extension to .zip used by container var below
|
// Vips overrides .dzi extension to .zip used by container var below
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('dz', info.format);
|
assert.strictEqual('dz', info.format);
|
||||||
fs.stat(container, function(err, stat) {
|
fs.stat(container, function (err, stat) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, stat.isFile());
|
assert.strictEqual(true, stat.isFile());
|
||||||
assert.strictEqual(true, stat.size > 0);
|
assert.strictEqual(true, stat.size > 0);
|
||||||
fs.createReadStream(container)
|
fs.createReadStream(container)
|
||||||
.pipe(unzip.Extract({path: path.dirname(extractTo)}))
|
.pipe(unzip.Extract({path: path.dirname(extractTo)}))
|
||||||
.on('error', function(err) { throw err; })
|
.on('error', function (err) { throw err; })
|
||||||
.on('close', function() {
|
.on('close', function () {
|
||||||
assertDeepZoomTiles(directory, 256, 13, done);
|
assertDeepZoomTiles(directory, 256, 13, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user