mirror of
https://github.com/lovell/sharp.git
synced 2026-02-08 07:36:16 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b87a20b881 | ||
|
|
0e6f2d16ab | ||
|
|
498b061819 | ||
|
|
5ab6f599fb | ||
|
|
8b80626035 | ||
|
|
f86ae79fdb | ||
|
|
1a4e68096f | ||
|
|
d599d1f29e | ||
|
|
73edfb3d2c | ||
|
|
ebae68d579 | ||
|
|
573836e2b8 |
@@ -2,13 +2,12 @@ build
|
|||||||
node_modules
|
node_modules
|
||||||
coverage
|
coverage
|
||||||
.editorconfig
|
.editorconfig
|
||||||
|
.gitattributes
|
||||||
.gitignore
|
.gitignore
|
||||||
test
|
test
|
||||||
.travis.yml
|
.travis.yml
|
||||||
appveyor.yml
|
appveyor.yml
|
||||||
circle.yml
|
|
||||||
mkdocs.yml
|
mkdocs.yml
|
||||||
vendor
|
vendor
|
||||||
packaging
|
|
||||||
preinstall.sh
|
|
||||||
.nyc_output
|
.nyc_output
|
||||||
|
CONTRIBUTING.md
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ Any change that modifies the existing public API should be added to the relevant
|
|||||||
|
|
||||||
| Release | WIP branch |
|
| Release | WIP branch |
|
||||||
| ------: | :--------- |
|
| ------: | :--------- |
|
||||||
| v0.19.0 | suit |
|
| v0.20.0 | prebuild |
|
||||||
| v0.20.0 | teeth |
|
| v0.21.0 | teeth |
|
||||||
|
| v0.22.0 | uptake |
|
||||||
|
|
||||||
Please squash your changes into a single commit using a command like `git rebase -i upstream/<wip-branch>`.
|
Please squash your changes into a single commit using a command like `git rebase -i upstream/<wip-branch>`.
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
- [convolve](#convolve)
|
- [convolve](#convolve)
|
||||||
- [threshold](#threshold)
|
- [threshold](#threshold)
|
||||||
- [boolean](#boolean)
|
- [boolean](#boolean)
|
||||||
|
- [linear](#linear)
|
||||||
|
|
||||||
## rotate
|
## rotate
|
||||||
|
|
||||||
@@ -318,6 +319,20 @@ the selected bitwise boolean `operation` between the corresponding pixels of the
|
|||||||
- `options.raw.channels` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
|
- `options.raw.channels` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
|
||||||
|
|
||||||
|
|
||||||
|
- Throws **[Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)** Invalid parameters
|
||||||
|
|
||||||
|
Returns **Sharp**
|
||||||
|
|
||||||
|
## linear
|
||||||
|
|
||||||
|
Apply the linear formula a \* input + b to the image (levels adjustment)
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `a` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** multiplier (optional, default `1.0`)
|
||||||
|
- `b` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** offset (optional, default `0.0`)
|
||||||
|
|
||||||
|
|
||||||
- Throws **[Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)** Invalid parameters
|
- Throws **[Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)** Invalid parameters
|
||||||
|
|
||||||
Returns **Sharp**
|
Returns **Sharp**
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ Use a `.zip` or `.szi` file extension with `toFile` to write to a compressed arc
|
|||||||
- `tile` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
|
- `tile` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
|
||||||
- `tile.size` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
|
- `tile.size` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
|
||||||
- `tile.overlap` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`)
|
- `tile.overlap` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`)
|
||||||
|
- `tile.angle` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** tile angle of rotation, must be a multiple of 90. (optional, default `0`)
|
||||||
- `tile.container` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
|
- `tile.container` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
|
||||||
- `tile.layout` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** filesystem layout, possible values are `dz`, `zoomify` or `google`. (optional, default `'dz'`)
|
- `tile.layout` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** filesystem layout, possible values are `dz`, `zoomify` or `google`. (optional, default `'dz'`)
|
||||||
|
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ Returns **Sharp**
|
|||||||
Do not enlarge the output image if the input image width _or_ height are already less than the required dimensions.
|
Do not enlarge the output image if the input image width _or_ height are already less than the required dimensions.
|
||||||
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_".
|
||||||
|
Use with `max()` to preserve the image's aspect ratio.
|
||||||
|
|
||||||
The default behaviour _before_ function call is `false`, meaning the image will be enlarged.
|
The default behaviour _before_ function call is `false`, meaning the image will be enlarged.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,20 @@
|
|||||||
|
|
||||||
Requires libvips v8.6.1.
|
Requires libvips v8.6.1.
|
||||||
|
|
||||||
|
#### v0.19.1 - 24<sup>th</sup> February 2018
|
||||||
|
|
||||||
|
* Expose libvips' linear transform feature.
|
||||||
|
[#1024](https://github.com/lovell/sharp/pull/1024)
|
||||||
|
[@3epnm](https://github.com/3epnm)
|
||||||
|
|
||||||
|
* Expose angle option for tile-based output.
|
||||||
|
[#1121](https://github.com/lovell/sharp/pull/1121)
|
||||||
|
[@BiancoA](https://github.com/BiancoA)
|
||||||
|
|
||||||
|
* Prevent crop operation when image already at or below target dimensions.
|
||||||
|
[#1134](https://github.com/lovell/sharp/issues/1134)
|
||||||
|
[@pieh](https://github.com/pieh)
|
||||||
|
|
||||||
#### v0.19.0 - 11<sup>th</sup> January 2018
|
#### v0.19.0 - 11<sup>th</sup> January 2018
|
||||||
|
|
||||||
* Expose offset coordinates of strategy-based crop.
|
* Expose offset coordinates of strategy-based crop.
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ the help and code contributions of the following people:
|
|||||||
* [Matthew McEachen](https://github.com/mceachen)
|
* [Matthew McEachen](https://github.com/mceachen)
|
||||||
* [Jarda Kotěšovec](https://github.com/jardakotesovec)
|
* [Jarda Kotěšovec](https://github.com/jardakotesovec)
|
||||||
* [Kenric D'Souza](https://github.com/AzureByte)
|
* [Kenric D'Souza](https://github.com/AzureByte)
|
||||||
|
* [Oleh Aleinyk](https://github.com/oaleynik)
|
||||||
|
* [Marcel Bretschneider](https://github.com/3epnm)
|
||||||
|
* [Andrea Bianco](https://github.com/BiancoA)
|
||||||
|
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ const Sharp = function (input, options) {
|
|||||||
tiffYres: 1.0,
|
tiffYres: 1.0,
|
||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
tileOverlap: 0,
|
tileOverlap: 0,
|
||||||
|
linearA: 1,
|
||||||
|
linearB: 0,
|
||||||
// Function to notify of libvips warnings
|
// Function to notify of libvips warnings
|
||||||
debuglog: debuglog,
|
debuglog: debuglog,
|
||||||
// Function to notify of queue length changes
|
// Function to notify of queue length changes
|
||||||
|
|||||||
@@ -406,6 +406,33 @@ function boolean (operand, operator, options) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the linear formula a * input + b to the image (levels adjustment)
|
||||||
|
* @param {Number} [a=1.0] multiplier
|
||||||
|
* @param {Number} [b=0.0] offset
|
||||||
|
* @returns {Sharp}
|
||||||
|
* @throws {Error} Invalid parameters
|
||||||
|
*/
|
||||||
|
function linear (a, b) {
|
||||||
|
if (!is.defined(a)) {
|
||||||
|
this.options.linearA = 1.0;
|
||||||
|
} else if (is.number(a)) {
|
||||||
|
this.options.linearA = a;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid linear transform multiplier ' + a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.defined(b)) {
|
||||||
|
this.options.linearB = 0.0;
|
||||||
|
} else if (is.number(b)) {
|
||||||
|
this.options.linearB = b;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid linear transform offset ' + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with operation-related functions.
|
* Decorate the Sharp prototype with operation-related functions.
|
||||||
* @private
|
* @private
|
||||||
@@ -427,7 +454,8 @@ module.exports = function (Sharp) {
|
|||||||
normalize,
|
normalize,
|
||||||
convolve,
|
convolve,
|
||||||
threshold,
|
threshold,
|
||||||
boolean
|
boolean,
|
||||||
|
linear
|
||||||
].forEach(function (f) {
|
].forEach(function (f) {
|
||||||
Sharp.prototype[f.name] = f;
|
Sharp.prototype[f.name] = f;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ function toFormat (format, options) {
|
|||||||
* @param {Object} [tile]
|
* @param {Object} [tile]
|
||||||
* @param {Number} [tile.size=256] tile size in pixels, a value between 1 and 8192.
|
* @param {Number} [tile.size=256] tile size in pixels, a value between 1 and 8192.
|
||||||
* @param {Number} [tile.overlap=0] tile overlap in pixels, a value between 0 and 8192.
|
* @param {Number} [tile.overlap=0] tile overlap in pixels, a value between 0 and 8192.
|
||||||
|
* @param {Number} [tile.angle=0] tile angle of rotation, must be a multiple of 90.
|
||||||
* @param {String} [tile.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file).
|
* @param {String} [tile.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file).
|
||||||
* @param {String} [tile.layout='dz'] filesystem layout, possible values are `dz`, `zoomify` or `google`.
|
* @param {String} [tile.layout='dz'] filesystem layout, possible values are `dz`, `zoomify` or `google`.
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
@@ -361,6 +362,15 @@ function tile (tile) {
|
|||||||
throw new Error('Invalid tile layout ' + tile.layout);
|
throw new Error('Invalid tile layout ' + tile.layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Angle of rotation,
|
||||||
|
if (is.defined(tile.angle)) {
|
||||||
|
if (is.integer(tile.angle) && !(tile.angle % 90)) {
|
||||||
|
this.options.tileAngle = tile.angle;
|
||||||
|
} else {
|
||||||
|
throw new Error('Unsupported angle: angle must be a positive/negative multiple of 90 ' + tile.angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Format
|
// Format
|
||||||
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
|
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
|
||||||
@@ -368,6 +378,7 @@ function tile (tile) {
|
|||||||
} else if (this.options.formatOut !== 'input') {
|
} else if (this.options.formatOut !== 'input') {
|
||||||
throw new Error('Invalid tile format ' + this.options.formatOut);
|
throw new Error('Invalid tile format ' + this.options.formatOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._updateFormatOut('dz');
|
return this._updateFormatOut('dz');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ function ignoreAspectRatio () {
|
|||||||
* Do not enlarge the output image if the input image width *or* height are already less than the required dimensions.
|
* Do not enlarge the output image if the input image width *or* height are already less than the required dimensions.
|
||||||
* 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*".
|
||||||
|
* Use with `max()` to preserve the image's aspect ratio.
|
||||||
*
|
*
|
||||||
* The default behaviour *before* function call is `false`, meaning the image will be enlarged.
|
* The default behaviour *before* function call is `false`, meaning the image will be enlarged.
|
||||||
*
|
*
|
||||||
|
|||||||
23
package.json
23
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||||
"version": "0.19.0",
|
"version": "0.19.1",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://github.com/lovell/sharp",
|
"homepage": "https://github.com/lovell/sharp",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -39,10 +39,13 @@
|
|||||||
"Guy Maliar <guy@tailorbrands.com>",
|
"Guy Maliar <guy@tailorbrands.com>",
|
||||||
"Nicolas Coden <nicolas@ncoden.fr>",
|
"Nicolas Coden <nicolas@ncoden.fr>",
|
||||||
"Matt Parrish <matt.r.parrish@gmail.com>",
|
"Matt Parrish <matt.r.parrish@gmail.com>",
|
||||||
|
"Marcel Bretschneider <marcel.bretschneider@gmail.com>",
|
||||||
"Matthew McEachen <matthew+github@mceachen.org>",
|
"Matthew McEachen <matthew+github@mceachen.org>",
|
||||||
"Jarda Kotěšovec <jarda.kotesovec@gmail.com>",
|
"Jarda Kotěšovec <jarda.kotesovec@gmail.com>",
|
||||||
"Kenric D'Souza <kenric.dsouza@gmail.com>",
|
"Kenric D'Souza <kenric.dsouza@gmail.com>",
|
||||||
"Oleh Aleinyk <oleg.aleynik@gmail.com>"
|
"Oleh Aleinyk <oleg.aleynik@gmail.com>",
|
||||||
|
"Marcel Bretschneider <marcel.bretschneider@gmail.com>",
|
||||||
|
"Andrea Bianco <andrea.bianco@unibas.ch>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf node_modules/ build/ vendor/ coverage/ test/fixtures/output.*",
|
"clean": "rm -rf node_modules/ build/ vendor/ coverage/ test/fixtures/output.*",
|
||||||
@@ -73,24 +76,24 @@
|
|||||||
"vips"
|
"vips"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color": "^2.0.1",
|
"color": "^3.0.0",
|
||||||
"detect-libc": "^1.0.3",
|
"detect-libc": "^1.0.3",
|
||||||
"nan": "^2.8.0",
|
"nan": "^2.9.2",
|
||||||
"semver": "^5.4.1",
|
"semver": "^5.5.0",
|
||||||
"simple-get": "^2.7.0",
|
"simple-get": "^2.7.0",
|
||||||
"tar": "^4.2.0",
|
"tar": "^4.4.0",
|
||||||
"tunnel-agent": "^0.6.0"
|
"tunnel-agent": "^0.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"async": "^2.6.0",
|
"async": "^2.6.0",
|
||||||
"cc": "^1.0.1",
|
"cc": "^1.0.1",
|
||||||
"documentation": "^5.3.5",
|
"documentation": "^5.4.0",
|
||||||
"exif-reader": "^1.0.2",
|
"exif-reader": "^1.0.2",
|
||||||
"icc": "^1.0.0",
|
"icc": "^1.0.0",
|
||||||
"mocha": "^4.1.0",
|
"mocha": "^5.0.1",
|
||||||
"nyc": "^11.4.1",
|
"nyc": "^11.5.0",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"semistandard": "^12.0.0",
|
"semistandard": "^12.0.1",
|
||||||
"unzip": "^0.1.11"
|
"unzip": "^0.1.11"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|||||||
MetadataWorker(
|
MetadataWorker(
|
||||||
Nan::Callback *callback, MetadataBaton *baton, Nan::Callback *debuglog,
|
Nan::Callback *callback, MetadataBaton *baton, Nan::Callback *debuglog,
|
||||||
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
||||||
Nan::AsyncWorker(callback), baton(baton), debuglog(debuglog),
|
Nan::AsyncWorker(callback, "sharp:MetadataWorker"),
|
||||||
|
baton(baton), debuglog(debuglog),
|
||||||
buffersToPersist(buffersToPersist) {
|
buffersToPersist(buffersToPersist) {
|
||||||
// Protect Buffer objects from GC, keyed on index
|
// Protect Buffer objects from GC, keyed on index
|
||||||
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
||||||
@@ -165,12 +166,12 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|||||||
std::string warning = sharp::VipsWarningPop();
|
std::string warning = sharp::VipsWarningPop();
|
||||||
while (!warning.empty()) {
|
while (!warning.empty()) {
|
||||||
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
||||||
debuglog->Call(1, message);
|
debuglog->Call(1, message, async_resource);
|
||||||
warning = sharp::VipsWarningPop();
|
warning = sharp::VipsWarningPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return to JavaScript
|
// Return to JavaScript
|
||||||
callback->Call(2, argv);
|
callback->Call(2, argv, async_resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -341,4 +341,18 @@ namespace sharp {
|
|||||||
return image.extract_area(left, top, width, height);
|
return image.extract_area(left, top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate (a * in + b)
|
||||||
|
*/
|
||||||
|
VImage Linear(VImage image, double const a, double const b) {
|
||||||
|
if (HasAlpha(image)) {
|
||||||
|
// Separate alpha channel
|
||||||
|
VImage imageWithoutAlpha = image.extract_band(0,
|
||||||
|
VImage::option()->set("n", image.bands() - 1));
|
||||||
|
VImage alpha = image[image.bands() - 1];
|
||||||
|
return imageWithoutAlpha.linear(a, b).bandjoin(alpha);
|
||||||
|
} else {
|
||||||
|
return image.linear(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace sharp
|
} // namespace sharp
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ namespace sharp {
|
|||||||
*/
|
*/
|
||||||
VImage Trim(VImage image, int const tolerance);
|
VImage Trim(VImage image, int const tolerance);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linear adjustment (a * in + b)
|
||||||
|
*/
|
||||||
|
VImage Linear(VImage image, double const a, double const b);
|
||||||
|
|
||||||
} // namespace sharp
|
} // namespace sharp
|
||||||
|
|
||||||
#endif // SRC_OPERATIONS_H_
|
#endif // SRC_OPERATIONS_H_
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
PipelineWorker(
|
PipelineWorker(
|
||||||
Nan::Callback *callback, PipelineBaton *baton, Nan::Callback *debuglog, Nan::Callback *queueListener,
|
Nan::Callback *callback, PipelineBaton *baton, Nan::Callback *debuglog, Nan::Callback *queueListener,
|
||||||
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
||||||
Nan::AsyncWorker(callback), baton(baton), debuglog(debuglog), queueListener(queueListener),
|
Nan::AsyncWorker(callback, "sharp:PipelineWorker"),
|
||||||
|
baton(baton), debuglog(debuglog), queueListener(queueListener),
|
||||||
buffersToPersist(buffersToPersist) {
|
buffersToPersist(buffersToPersist) {
|
||||||
// Protect Buffer objects from GC, keyed on index
|
// Protect Buffer objects from GC, keyed on index
|
||||||
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
||||||
@@ -465,7 +466,10 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
->set("extend", VIPS_EXTEND_BACKGROUND)
|
->set("extend", VIPS_EXTEND_BACKGROUND)
|
||||||
->set("background", background));
|
->set("background", background));
|
||||||
|
|
||||||
} else if (baton->canvas != Canvas::IGNORE_ASPECT) {
|
} else if (
|
||||||
|
baton->canvas != Canvas::IGNORE_ASPECT &&
|
||||||
|
(image.width() > baton->width || image.height() > baton->height)
|
||||||
|
) {
|
||||||
// Crop/max/min
|
// Crop/max/min
|
||||||
if (baton->crop < 9) {
|
if (baton->crop < 9) {
|
||||||
// Gravity-based crop
|
// Gravity-based crop
|
||||||
@@ -644,6 +648,11 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
image = sharp::Gamma(image, baton->gamma);
|
image = sharp::Gamma(image, baton->gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Linear adjustment (a * in + b)
|
||||||
|
if (baton->linearA != 1.0 || baton->linearB != 0.0) {
|
||||||
|
image = sharp::Linear(image, baton->linearA, baton->linearB);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply normalisation - stretch luminance to cover full dynamic range
|
// Apply normalisation - stretch luminance to cover full dynamic range
|
||||||
if (baton->normalise) {
|
if (baton->normalise) {
|
||||||
image = sharp::Normalise(image);
|
image = sharp::Normalise(image);
|
||||||
@@ -912,7 +921,8 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
->set("overlap", baton->tileOverlap)
|
->set("overlap", baton->tileOverlap)
|
||||||
->set("container", baton->tileContainer)
|
->set("container", baton->tileContainer)
|
||||||
->set("layout", baton->tileLayout)
|
->set("layout", baton->tileLayout)
|
||||||
->set("suffix", const_cast<char*>(suffix.data())));
|
->set("suffix", const_cast<char*>(suffix.data()))
|
||||||
|
->set("angle", CalculateAngleRotation(baton->tileAngle)));
|
||||||
baton->formatOut = "dz";
|
baton->formatOut = "dz";
|
||||||
} else if (baton->formatOut == "v" || (mightMatchInput && isV) ||
|
} else if (baton->formatOut == "v" || (mightMatchInput && isV) ||
|
||||||
(willMatchInput && inputImageType == ImageType::VIPS)) {
|
(willMatchInput && inputImageType == ImageType::VIPS)) {
|
||||||
@@ -1005,18 +1015,18 @@ class PipelineWorker : public Nan::AsyncWorker {
|
|||||||
std::string warning = sharp::VipsWarningPop();
|
std::string warning = sharp::VipsWarningPop();
|
||||||
while (!warning.empty()) {
|
while (!warning.empty()) {
|
||||||
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
||||||
debuglog->Call(1, message);
|
debuglog->Call(1, message, async_resource);
|
||||||
warning = sharp::VipsWarningPop();
|
warning = sharp::VipsWarningPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrement processing task counter
|
// Decrement processing task counter
|
||||||
g_atomic_int_dec_and_test(&sharp::counterProcess);
|
g_atomic_int_dec_and_test(&sharp::counterProcess);
|
||||||
v8::Local<v8::Value> queueLength[1] = { New<v8::Uint32>(sharp::counterQueue) };
|
v8::Local<v8::Value> queueLength[1] = { New<v8::Uint32>(sharp::counterQueue) };
|
||||||
queueListener->Call(1, queueLength);
|
queueListener->Call(1, queueLength, async_resource);
|
||||||
delete queueListener;
|
delete queueListener;
|
||||||
|
|
||||||
// Return to JavaScript
|
// Return to JavaScript
|
||||||
callback->Call(3, argv);
|
callback->Call(3, argv, async_resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1185,6 +1195,8 @@ NAN_METHOD(pipeline) {
|
|||||||
baton->thresholdGrayscale = AttrTo<bool>(options, "thresholdGrayscale");
|
baton->thresholdGrayscale = AttrTo<bool>(options, "thresholdGrayscale");
|
||||||
baton->trimTolerance = AttrTo<int32_t>(options, "trimTolerance");
|
baton->trimTolerance = AttrTo<int32_t>(options, "trimTolerance");
|
||||||
baton->gamma = AttrTo<double>(options, "gamma");
|
baton->gamma = AttrTo<double>(options, "gamma");
|
||||||
|
baton->linearA = AttrTo<double>(options, "linearA");
|
||||||
|
baton->linearB = AttrTo<double>(options, "linearB");
|
||||||
baton->greyscale = AttrTo<bool>(options, "greyscale");
|
baton->greyscale = AttrTo<bool>(options, "greyscale");
|
||||||
baton->normalise = AttrTo<bool>(options, "normalise");
|
baton->normalise = AttrTo<bool>(options, "normalise");
|
||||||
baton->useExifOrientation = AttrTo<bool>(options, "useExifOrientation");
|
baton->useExifOrientation = AttrTo<bool>(options, "useExifOrientation");
|
||||||
@@ -1256,6 +1268,7 @@ NAN_METHOD(pipeline) {
|
|||||||
baton->tileSize = AttrTo<uint32_t>(options, "tileSize");
|
baton->tileSize = AttrTo<uint32_t>(options, "tileSize");
|
||||||
baton->tileOverlap = AttrTo<uint32_t>(options, "tileOverlap");
|
baton->tileOverlap = AttrTo<uint32_t>(options, "tileOverlap");
|
||||||
std::string tileContainer = AttrAsStr(options, "tileContainer");
|
std::string tileContainer = AttrAsStr(options, "tileContainer");
|
||||||
|
baton->tileAngle = AttrTo<int32_t>(options, "tileAngle");
|
||||||
if (tileContainer == "zip") {
|
if (tileContainer == "zip") {
|
||||||
baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
|
baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
|
||||||
} else {
|
} else {
|
||||||
@@ -1290,5 +1303,6 @@ NAN_METHOD(pipeline) {
|
|||||||
// Increment queued task counter
|
// Increment queued task counter
|
||||||
g_atomic_int_inc(&sharp::counterQueue);
|
g_atomic_int_inc(&sharp::counterQueue);
|
||||||
v8::Local<v8::Value> queueLength[1] = { Nan::New<v8::Uint32>(sharp::counterQueue) };
|
v8::Local<v8::Value> queueLength[1] = { Nan::New<v8::Uint32>(sharp::counterQueue) };
|
||||||
queueListener->Call(1, queueLength);
|
v8::Local<v8::Object> recv = Nan::New<v8::Object>();
|
||||||
|
Nan::Call(*queueListener, recv, 1, queueLength);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ struct PipelineBaton {
|
|||||||
int threshold;
|
int threshold;
|
||||||
bool thresholdGrayscale;
|
bool thresholdGrayscale;
|
||||||
int trimTolerance;
|
int trimTolerance;
|
||||||
|
double linearA;
|
||||||
|
double linearB;
|
||||||
double gamma;
|
double gamma;
|
||||||
bool greyscale;
|
bool greyscale;
|
||||||
bool normalise;
|
bool normalise;
|
||||||
@@ -130,6 +132,7 @@ struct PipelineBaton {
|
|||||||
VipsForeignDzContainer tileContainer;
|
VipsForeignDzContainer tileContainer;
|
||||||
VipsForeignDzLayout tileLayout;
|
VipsForeignDzLayout tileLayout;
|
||||||
std::string tileFormat;
|
std::string tileFormat;
|
||||||
|
int tileAngle;
|
||||||
|
|
||||||
PipelineBaton():
|
PipelineBaton():
|
||||||
input(nullptr),
|
input(nullptr),
|
||||||
@@ -160,6 +163,8 @@ struct PipelineBaton {
|
|||||||
threshold(0),
|
threshold(0),
|
||||||
thresholdGrayscale(true),
|
thresholdGrayscale(true),
|
||||||
trimTolerance(0),
|
trimTolerance(0),
|
||||||
|
linearA(1.0),
|
||||||
|
linearB(0.0),
|
||||||
gamma(0.0),
|
gamma(0.0),
|
||||||
greyscale(false),
|
greyscale(false),
|
||||||
normalise(false),
|
normalise(false),
|
||||||
@@ -202,7 +207,8 @@ struct PipelineBaton {
|
|||||||
tileSize(256),
|
tileSize(256),
|
||||||
tileOverlap(0),
|
tileOverlap(0),
|
||||||
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
|
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
|
||||||
tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ) {
|
tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ),
|
||||||
|
tileAngle(0){
|
||||||
background[0] = 0.0;
|
background[0] = 0.0;
|
||||||
background[1] = 0.0;
|
background[1] = 0.0;
|
||||||
background[2] = 0.0;
|
background[2] = 0.0;
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ class StatsWorker : public Nan::AsyncWorker {
|
|||||||
StatsWorker(
|
StatsWorker(
|
||||||
Nan::Callback *callback, StatsBaton *baton, Nan::Callback *debuglog,
|
Nan::Callback *callback, StatsBaton *baton, Nan::Callback *debuglog,
|
||||||
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
std::vector<v8::Local<v8::Object>> const buffersToPersist) :
|
||||||
Nan::AsyncWorker(callback), baton(baton), debuglog(debuglog),
|
Nan::AsyncWorker(callback, "sharp:StatsWorker"),
|
||||||
|
baton(baton), debuglog(debuglog),
|
||||||
buffersToPersist(buffersToPersist) {
|
buffersToPersist(buffersToPersist) {
|
||||||
// Protect Buffer objects from GC, keyed on index
|
// Protect Buffer objects from GC, keyed on index
|
||||||
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
std::accumulate(buffersToPersist.begin(), buffersToPersist.end(), 0,
|
||||||
@@ -145,12 +146,12 @@ class StatsWorker : public Nan::AsyncWorker {
|
|||||||
std::string warning = sharp::VipsWarningPop();
|
std::string warning = sharp::VipsWarningPop();
|
||||||
while (!warning.empty()) {
|
while (!warning.empty()) {
|
||||||
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
v8::Local<v8::Value> message[1] = { New(warning).ToLocalChecked() };
|
||||||
debuglog->Call(1, message);
|
debuglog->Call(1, message, async_resource);
|
||||||
warning = sharp::VipsWarningPop();
|
warning = sharp::VipsWarningPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return to JavaScript
|
// Return to JavaScript
|
||||||
callback->Call(2, argv);
|
callback->Call(2, argv, async_resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
BIN
test/fixtures/expected/alpha-layer-1-fill-linear.png
vendored
Normal file
BIN
test/fixtures/expected/alpha-layer-1-fill-linear.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
BIN
test/fixtures/expected/alpha-layer-1-fill-offset.png
vendored
Normal file
BIN
test/fixtures/expected/alpha-layer-1-fill-offset.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
BIN
test/fixtures/expected/alpha-layer-1-fill-slope.png
vendored
Normal file
BIN
test/fixtures/expected/alpha-layer-1-fill-slope.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 179 KiB |
BIN
test/fixtures/expected/low-contrast-linear.jpg
vendored
Normal file
BIN
test/fixtures/expected/low-contrast-linear.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
test/fixtures/expected/low-contrast-offset.jpg
vendored
Normal file
BIN
test/fixtures/expected/low-contrast-offset.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
BIN
test/fixtures/expected/low-contrast-slope.jpg
vendored
Normal file
BIN
test/fixtures/expected/low-contrast-slope.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -159,6 +159,24 @@ describe('Crop', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Skip crop when post-resize dimensions are at or below target dimensions', function () {
|
||||||
|
return sharp(fixtures.inputJpg)
|
||||||
|
.resize(1600, 1200)
|
||||||
|
.toBuffer()
|
||||||
|
.then(function (input) {
|
||||||
|
return sharp(input)
|
||||||
|
.resize(1110)
|
||||||
|
.crop(sharp.strategy.attention)
|
||||||
|
.toBuffer({ resolveWithObject: true })
|
||||||
|
.then(function (result) {
|
||||||
|
assert.strictEqual(1110, result.info.width);
|
||||||
|
assert.strictEqual(832, result.info.height);
|
||||||
|
assert.strictEqual(undefined, result.info.cropOffsetLeft);
|
||||||
|
assert.strictEqual(undefined, result.info.cropOffsetTop);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Entropy-based strategy', function () {
|
describe('Entropy-based strategy', function () {
|
||||||
it('JPEG', function (done) {
|
it('JPEG', function (done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
|
|||||||
79
test/unit/linear.js
Normal file
79
test/unit/linear.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const sharp = require('../../');
|
||||||
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
describe('Linear adjustment', function () {
|
||||||
|
const blackPoint = 70;
|
||||||
|
const whitePoint = 203;
|
||||||
|
const a = 255 / (whitePoint - blackPoint);
|
||||||
|
const b = -blackPoint * a;
|
||||||
|
|
||||||
|
it('applies linear levels adjustment w/o alpha ch', function (done) {
|
||||||
|
sharp(fixtures.inputJpgWithLowContrast)
|
||||||
|
.linear(a, b)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('low-contrast-linear.jpg'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies slope level adjustment w/o alpha ch', function (done) {
|
||||||
|
sharp(fixtures.inputJpgWithLowContrast)
|
||||||
|
.linear(a)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('low-contrast-slope.jpg'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies offset level adjustment w/o alpha ch', function (done) {
|
||||||
|
sharp(fixtures.inputJpgWithLowContrast)
|
||||||
|
.linear(null, b)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('low-contrast-offset.jpg'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies linear levels adjustment w alpha ch', function (done) {
|
||||||
|
sharp(fixtures.inputPngOverlayLayer1)
|
||||||
|
.linear(a, b)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('alpha-layer-1-fill-linear.png'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies slope level adjustment w alpha ch', function (done) {
|
||||||
|
sharp(fixtures.inputPngOverlayLayer1)
|
||||||
|
.linear(a)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('alpha-layer-1-fill-slope.png'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies offset level adjustment w alpha ch', function (done) {
|
||||||
|
sharp(fixtures.inputPngOverlayLayer1)
|
||||||
|
.linear(null, b)
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('alpha-layer-1-fill-offset.png'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid linear arguments', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp(fixtures.inputPngOverlayLayer1)
|
||||||
|
.linear('foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp(fixtures.inputPngOverlayLayer1)
|
||||||
|
.linear(undefined, { 'bar': 'baz' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -146,13 +146,38 @@ 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
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Valid rotation angle values pass', function () {
|
||||||
|
[90, 270, -90].forEach(function (angle) {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tile({
|
||||||
|
angle: angle
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid rotation angle values fail', function () {
|
||||||
|
['zoinks', 1.1, -1, 27].forEach(function (angle) {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tile({
|
||||||
|
angle: angle
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -192,6 +217,40 @@ describe('Tile', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Deep Zoom layout with custom size+angle', function (done) {
|
||||||
|
const directory = fixtures.path('output.512_90.dzi_files');
|
||||||
|
rimraf(directory, function () {
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.tile({
|
||||||
|
size: 512,
|
||||||
|
angle: 90
|
||||||
|
})
|
||||||
|
.toFile(fixtures.path('output.512_90.dzi'), function (err, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('dz', info.format);
|
||||||
|
assert.strictEqual(2725, info.width);
|
||||||
|
assert.strictEqual(2225, info.height);
|
||||||
|
assert.strictEqual(3, info.channels);
|
||||||
|
assert.strictEqual('undefined', typeof info.size);
|
||||||
|
assertDeepZoomTiles(directory, 512, 13, done);
|
||||||
|
// Verifies tiles in 10th level are rotated
|
||||||
|
let tile = path.join(directory, '10', '0_1.jpeg');
|
||||||
|
// verify that the width and height correspond to the rotated image
|
||||||
|
// expected are w=512 and h=170 for the 0_1.jpeg.
|
||||||
|
// if a 0 angle is supplied to the .tile function
|
||||||
|
// the expected values are w=170 and h=512 for the 1_0.jpeg
|
||||||
|
sharp(tile).metadata(function (err, metadata) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
assert.strictEqual(true, metadata.width === 512);
|
||||||
|
assert.strictEqual(true, metadata.height === 170);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Zoomify layout', function (done) {
|
it('Zoomify layout', function (done) {
|
||||||
const directory = fixtures.path('output.zoomify.dzi');
|
const directory = fixtures.path('output.zoomify.dzi');
|
||||||
rimraf(directory, function () {
|
rimraf(directory, function () {
|
||||||
@@ -244,7 +303,9 @@ describe('Tile', function () {
|
|||||||
const directory = fixtures.path('output.jpg.google.dzi');
|
const directory = fixtures.path('output.jpg.google.dzi');
|
||||||
rimraf(directory, function () {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.jpeg({ quality: 1 })
|
.jpeg({
|
||||||
|
quality: 1
|
||||||
|
})
|
||||||
.tile({
|
.tile({
|
||||||
layout: 'google'
|
layout: 'google'
|
||||||
})
|
})
|
||||||
@@ -279,7 +340,9 @@ describe('Tile', function () {
|
|||||||
const directory = fixtures.path('output.png.google.dzi');
|
const directory = fixtures.path('output.png.google.dzi');
|
||||||
rimraf(directory, function () {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.png({ compressionLevel: 1 })
|
.png({
|
||||||
|
compressionLevel: 1
|
||||||
|
})
|
||||||
.tile({
|
.tile({
|
||||||
layout: 'google'
|
layout: 'google'
|
||||||
})
|
})
|
||||||
@@ -314,7 +377,9 @@ describe('Tile', function () {
|
|||||||
const directory = fixtures.path('output.webp.google.dzi');
|
const directory = fixtures.path('output.webp.google.dzi');
|
||||||
rimraf(directory, function () {
|
rimraf(directory, function () {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.webp({ quality: 1 })
|
.webp({
|
||||||
|
quality: 1
|
||||||
|
})
|
||||||
.tile({
|
.tile({
|
||||||
layout: 'google'
|
layout: 'google'
|
||||||
})
|
})
|
||||||
@@ -363,8 +428,12 @@ describe('Tile', function () {
|
|||||||
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({
|
||||||
.on('error', function (err) { throw err; })
|
path: path.dirname(extractTo)
|
||||||
|
}))
|
||||||
|
.on('error', function (err) {
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
.on('close', function () {
|
.on('close', function () {
|
||||||
assertDeepZoomTiles(directory, 256, 13, done);
|
assertDeepZoomTiles(directory, 256, 13, done);
|
||||||
});
|
});
|
||||||
@@ -395,8 +464,12 @@ describe('Tile', function () {
|
|||||||
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({
|
||||||
.on('error', function (err) { throw err; })
|
path: path.dirname(extractTo)
|
||||||
|
}))
|
||||||
|
.on('error', function (err) {
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
.on('close', function () {
|
.on('close', function () {
|
||||||
assertDeepZoomTiles(directory, 256, 13, done);
|
assertDeepZoomTiles(directory, 256, 13, done);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user