Compare commits

..

21 Commits

Author SHA1 Message Date
Lovell Fuller
aa3ce760bb Release v0.23.1 2019-09-26 10:19:06 +01:00
Lovell Fuller
ba46ad1fd9 Docs: mention removal of metadata in output methods 2019-09-25 16:56:52 +01:00
Lovell Fuller
11214bab5d Bump tar dependency to ensure minipass >=2.8.6 2019-09-25 14:31:54 +01:00
Lovell Fuller
d87c289b4a Update results from latest benchmark test run 2019-09-25 14:16:51 +01:00
Lovell Fuller
af45c03b6f Bump benchmark dependencies ahead of a perf test run 2019-09-25 12:03:16 +01:00
Lovell Fuller
7d6fadce6b Ensure promise-based benchmark test is fairer
Real-world code will register a catch handler
2019-09-25 12:01:43 +01:00
Lovell Fuller
6b560f7a85 Remove imagemagick-native module from benchmarks
Unmaintained, does not compile with newer ImageMagick and Node
2019-09-25 10:13:45 +01:00
Lovell Fuller
5d4221460d Docs: Add more prominent link to libvips 2019-09-24 10:53:33 +01:00
Lovell Fuller
d42c383992 Add link from GitHub to libvips OpenCollective 2019-09-24 10:49:52 +01:00
Lovell Fuller
9c7f6fcb2b Replace deprecated URL parser
Fix up various linter errors
2019-09-22 22:46:48 +01:00
Lovell Fuller
14af0bda61 Regenerate flatten-rgb16-orange test expectation, reduce threshold 2019-09-21 20:01:15 +01:00
Raboliot le gris
fb5c393fbd Allow instance reuse with differing toBuffer options (#1860) 2019-09-08 14:35:16 +01:00
Lovell Fuller
69fe21a7ec Ensure invalid resize width/height as options throw #1817 2019-08-16 21:21:12 +01:00
Lovell Fuller
da4e05c118 Better validation and test coverage for background colours 2019-08-16 20:37:17 +01:00
Lovell Fuller
e4333ff6b0 Changelog entry, credit and doc update for #1835 2019-08-14 20:17:31 +01:00
Andargor
4ae8999f62 Add premultiplied option to composite operation (#1835) 2019-08-14 19:01:23 +01:00
Lovell Fuller
3fa91bb4ce Ensure image >= 3x3 before attempting trim operation
See https://github.com/libvips/libvips/issues/1392
2019-08-13 21:34:49 +01:00
Lovell Fuller
23b2e541ab Changelog entry for #1834 2019-08-12 21:45:29 +01:00
Julian Aubourg
5bfcf61a6f Allow use of heic/heif identifiers with toFormat (#1834) 2019-08-12 21:36:56 +01:00
Lovell Fuller
0778c112a9 Ensure sharp.format.vips is present and correct #1813 2019-08-12 21:25:10 +01:00
Lovell Fuller
2c300754a7 Expand issue templates to direct towards installation 2019-07-31 16:48:32 +01:00
43 changed files with 797 additions and 589 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
open_collective: libvips

View File

@@ -1,16 +1,18 @@
---
name: Installation
about: For help if something went wrong installing sharp
about: Something went wrong **installing** sharp
title: ''
labels: ''
labels: installation
assignees: ''
---
What is the output of running `npm install --verbose sharp`?
What is the output of running `npx envinfo --binaries --languages --system --utilities`?
Did you see the [documentation relating to installation](https://sharp.pixelplumbing.com/en/stable/install/)?
Have you ensured the platform and version of Node.js used for `npm install` is the same as the platform and version of Node.js used at runtime?
If you're using `sudo npm install` have you tried with the `sudo npm install --unsafe-perm` flag?
If you're (mis)using `sudo npm install` have you tried with the `sudo npm install --unsafe-perm` flag?
What is the complete output of running `npm install --verbose sharp`? Have you checked this output for useful error messages?
What is the output of running `npx envinfo --binaries --languages --system --utilities`?

View File

@@ -1,12 +1,14 @@
---
name: Possible bug
about: Please provide steps to reproduce
about: Something unexpected occurred **using** sharp
title: ''
labels: ''
labels: triage
assignees: ''
---
<!-- If this issue relates to installation, please use https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md instead. -->
What is the output of running `npx envinfo --binaries --languages --system --utilities`?
What are the steps to reproduce?

View File

@@ -1,12 +1,14 @@
---
name: Question
about: For help with an existing feature
about: For help understanding an existing feature
title: ''
labels: question
assignees: ''
---
<!-- If this issue relates to installation, please use https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md instead. -->
What are you trying to achieve?
Have you searched for similar questions?

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ vendor
.nyc_output
.vscode/
package-lock.json
.idea

View File

@@ -11,7 +11,8 @@ is to convert large images in common formats to
smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings.
quickest ImageMagick and GraphicsMagick settings
due to its use of [libvips](https://github.com/libvips/libvips).
Colour spaces, embedded ICC profiles and alpha transparency channels are all handled correctly.
Lanczos resampling ensures quality is not sacrificed for speed.

View File

@@ -31,6 +31,7 @@ and [https://www.cairographics.org/operators/][2]
- `images[].top` **[Number][7]?** the pixel offset from the top edge.
- `images[].left` **[Number][7]?** the pixel offset from the left edge.
- `images[].tile` **[Boolean][9]** set to true to repeat the overlay image across the entire image with the given `gravity`. (optional, default `false`)
- `images[].premultiplied` **[Boolean][9]** set to true to avoid premultipling the image below. Equivalent to the `--premultiplied` vips option. (optional, default `false`)
- `images[].density` **[Number][7]** number representing the DPI for vector overlay image. (optional, default `72`)
- `images[].raw` **[Object][4]?** describes overlay when using raw pixel data.
- `images[].raw.width` **[Number][7]?**

View File

@@ -8,12 +8,15 @@ If an explicit output format is not selected, it will be inferred from the exten
with JPEG, PNG, WebP, TIFF, DZI, and libvips' V format supported.
Note that raw pixel data is only supported for buffer output.
By default all metadata will be removed, which includes EXIF-based orientation.
See [withMetadata][1] for control over this.
A `Promise` is returned when `callback` is not provided.
### Parameters
- `fileOut` **[String][1]** the path to write the image data to.
- `callback` **[Function][2]?** called on completion with two arguments `(err, info)`.
- `fileOut` **[String][2]** the path to write the image data to.
- `callback` **[Function][3]?** called on completion with two arguments `(err, info)`.
`info` contains the output image `format`, `size` (bytes), `width`, `height`,
`channels` and `premultiplied` (indicating if premultiplication was used).
When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
@@ -32,15 +35,19 @@ sharp(input)
.catch(err => { ... });
```
- Throws **[Error][3]** Invalid parameters
- Throws **[Error][4]** Invalid parameters
Returns **[Promise][4]&lt;[Object][5]>** when no callback is provided
Returns **[Promise][5]&lt;[Object][6]>** when no callback is provided
## toBuffer
Write output to a Buffer.
JPEG, PNG, WebP, TIFF and RAW output are supported.
By default, the format will match the input image, except GIF and SVG input which become PNG output.
If no explicit format is set, the output format will match the input image, except GIF and SVG input which become PNG output.
By default all metadata will be removed, which includes EXIF-based orientation.
See [withMetadata][1] for control over this.
`callback`, if present, gets three arguments `(err, data, info)` where:
@@ -54,9 +61,9 @@ A `Promise` is returned when `callback` is not provided.
### Parameters
- `options` **[Object][5]?**
- `options.resolveWithObject` **[Boolean][6]?** Resolve the Promise with an Object containing `data` and `info` properties instead of resolving only with `data`.
- `callback` **[Function][2]?**
- `options` **[Object][6]?**
- `options.resolveWithObject` **[Boolean][7]?** Resolve the Promise with an Object containing `data` and `info` properties instead of resolving only with `data`.
- `callback` **[Function][3]?**
### Examples
@@ -79,7 +86,7 @@ sharp(input)
.catch(err => { ... });
```
Returns **[Promise][4]&lt;[Buffer][7]>** when no callback is provided
Returns **[Promise][5]&lt;[Buffer][8]>** when no callback is provided
## withMetadata
@@ -89,8 +96,8 @@ This will also convert to and add a web-friendly sRGB ICC profile.
### Parameters
- `options` **[Object][5]?**
- `options.orientation` **[Number][8]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
- `options` **[Object][6]?**
- `options.orientation` **[Number][9]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
### Examples
@@ -101,7 +108,7 @@ sharp('input.jpg')
.then(info => { ... });
```
- Throws **[Error][3]** Invalid parameters
- Throws **[Error][4]** Invalid parameters
Returns **Sharp**
@@ -111,19 +118,19 @@ Use these JPEG options for output image.
### Parameters
- `options` **[Object][5]?** output options
- `options.quality` **[Number][8]** quality, integer 1-100 (optional, default `80`)
- `options.progressive` **[Boolean][6]** use progressive (interlace) scan (optional, default `false`)
- `options.chromaSubsampling` **[String][1]** set to '4:4:4' to prevent chroma subsampling when quality &lt;= 90 (optional, default `'4:2:0'`)
- `options.trellisQuantisation` **[Boolean][6]** apply trellis quantisation, requires libvips compiled with support for mozjpeg (optional, default `false`)
- `options.overshootDeringing` **[Boolean][6]** apply overshoot deringing, requires libvips compiled with support for mozjpeg (optional, default `false`)
- `options.optimiseScans` **[Boolean][6]** optimise progressive scans, forces progressive, requires libvips compiled with support for mozjpeg (optional, default `false`)
- `options.optimizeScans` **[Boolean][6]** alternative spelling of optimiseScans (optional, default `false`)
- `options.optimiseCoding` **[Boolean][6]** optimise Huffman coding tables (optional, default `true`)
- `options.optimizeCoding` **[Boolean][6]** alternative spelling of optimiseCoding (optional, default `true`)
- `options.quantisationTable` **[Number][8]** quantization table to use, integer 0-8, requires libvips compiled with support for mozjpeg (optional, default `0`)
- `options.quantizationTable` **[Number][8]** alternative spelling of quantisationTable (optional, default `0`)
- `options.force` **[Boolean][6]** force JPEG output, otherwise attempt to use input format (optional, default `true`)
- `options` **[Object][6]?** output options
- `options.quality` **[Number][9]** quality, integer 1-100 (optional, default `80`)
- `options.progressive` **[Boolean][7]** use progressive (interlace) scan (optional, default `false`)
- `options.chromaSubsampling` **[String][2]** set to '4:4:4' to prevent chroma subsampling when quality &lt;= 90 (optional, default `'4:2:0'`)
- `options.trellisQuantisation` **[Boolean][7]** apply trellis quantisation, requires libvips compiled with support for mozjpeg (optional, default `false`)
- `options.overshootDeringing` **[Boolean][7]** apply overshoot deringing, requires libvips compiled with support for mozjpeg (optional, default `false`)
- `options.optimiseScans` **[Boolean][7]** optimise progressive scans, forces progressive, requires libvips compiled with support for mozjpeg (optional, default `false`)
- `options.optimizeScans` **[Boolean][7]** alternative spelling of optimiseScans (optional, default `false`)
- `options.optimiseCoding` **[Boolean][7]** optimise Huffman coding tables (optional, default `true`)
- `options.optimizeCoding` **[Boolean][7]** alternative spelling of optimiseCoding (optional, default `true`)
- `options.quantisationTable` **[Number][9]** quantization table to use, integer 0-8, requires libvips compiled with support for mozjpeg (optional, default `0`)
- `options.quantizationTable` **[Number][9]** alternative spelling of quantisationTable (optional, default `0`)
- `options.force` **[Boolean][7]** force JPEG output, otherwise attempt to use input format (optional, default `true`)
### Examples
@@ -137,7 +144,7 @@ const data = await sharp(input)
.toBuffer();
```
- Throws **[Error][3]** Invalid options
- Throws **[Error][4]** Invalid options
Returns **Sharp**
@@ -150,16 +157,16 @@ Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel.
### Parameters
- `options` **[Object][5]?**
- `options.progressive` **[Boolean][6]** use progressive (interlace) scan (optional, default `false`)
- `options.compressionLevel` **[Number][8]** zlib compression level, 0-9 (optional, default `9`)
- `options.adaptiveFiltering` **[Boolean][6]** use adaptive row filtering (optional, default `false`)
- `options.palette` **[Boolean][6]** quantise to a palette-based image with alpha transparency support, requires libvips compiled with support for libimagequant (optional, default `false`)
- `options.quality` **[Number][8]** use the lowest number of colours needed to achieve given quality, requires libvips compiled with support for libimagequant (optional, default `100`)
- `options.colours` **[Number][8]** maximum number of palette entries, requires libvips compiled with support for libimagequant (optional, default `256`)
- `options.colors` **[Number][8]** alternative spelling of `options.colours`, requires libvips compiled with support for libimagequant (optional, default `256`)
- `options.dither` **[Number][8]** level of Floyd-Steinberg error diffusion, requires libvips compiled with support for libimagequant (optional, default `1.0`)
- `options.force` **[Boolean][6]** force PNG output, otherwise attempt to use input format (optional, default `true`)
- `options` **[Object][6]?**
- `options.progressive` **[Boolean][7]** use progressive (interlace) scan (optional, default `false`)
- `options.compressionLevel` **[Number][9]** zlib compression level, 0-9 (optional, default `9`)
- `options.adaptiveFiltering` **[Boolean][7]** use adaptive row filtering (optional, default `false`)
- `options.palette` **[Boolean][7]** quantise to a palette-based image with alpha transparency support, requires libvips compiled with support for libimagequant (optional, default `false`)
- `options.quality` **[Number][9]** use the lowest number of colours needed to achieve given quality, requires libvips compiled with support for libimagequant (optional, default `100`)
- `options.colours` **[Number][9]** maximum number of palette entries, requires libvips compiled with support for libimagequant (optional, default `256`)
- `options.colors` **[Number][9]** alternative spelling of `options.colours`, requires libvips compiled with support for libimagequant (optional, default `256`)
- `options.dither` **[Number][9]** level of Floyd-Steinberg error diffusion, requires libvips compiled with support for libimagequant (optional, default `1.0`)
- `options.force` **[Boolean][7]** force PNG output, otherwise attempt to use input format (optional, default `true`)
### Examples
@@ -170,7 +177,7 @@ const data = await sharp(input)
.toBuffer();
```
- Throws **[Error][3]** Invalid options
- Throws **[Error][4]** Invalid options
Returns **Sharp**
@@ -180,14 +187,14 @@ Use these WebP options for output image.
### Parameters
- `options` **[Object][5]?** output options
- `options.quality` **[Number][8]** quality, integer 1-100 (optional, default `80`)
- `options.alphaQuality` **[Number][8]** quality of alpha layer, integer 0-100 (optional, default `100`)
- `options.lossless` **[Boolean][6]** use lossless compression mode (optional, default `false`)
- `options.nearLossless` **[Boolean][6]** use near_lossless compression mode (optional, default `false`)
- `options.smartSubsample` **[Boolean][6]** use high quality chroma subsampling (optional, default `false`)
- `options.reductionEffort` **[Number][8]** level of CPU effort to reduce file size, integer 0-6 (optional, default `4`)
- `options.force` **[Boolean][6]** force WebP output, otherwise attempt to use input format (optional, default `true`)
- `options` **[Object][6]?** output options
- `options.quality` **[Number][9]** quality, integer 1-100 (optional, default `80`)
- `options.alphaQuality` **[Number][9]** quality of alpha layer, integer 0-100 (optional, default `100`)
- `options.lossless` **[Boolean][7]** use lossless compression mode (optional, default `false`)
- `options.nearLossless` **[Boolean][7]** use near_lossless compression mode (optional, default `false`)
- `options.smartSubsample` **[Boolean][7]** use high quality chroma subsampling (optional, default `false`)
- `options.reductionEffort` **[Number][9]** level of CPU effort to reduce file size, integer 0-6 (optional, default `4`)
- `options.force` **[Boolean][7]** force WebP output, otherwise attempt to use input format (optional, default `true`)
### Examples
@@ -198,7 +205,7 @@ const data = await sharp(input)
.toBuffer();
```
- Throws **[Error][3]** Invalid options
- Throws **[Error][4]** Invalid options
Returns **Sharp**
@@ -208,18 +215,18 @@ Use these TIFF options for output image.
### Parameters
- `options` **[Object][5]?** output options
- `options.quality` **[Number][8]** quality, integer 1-100 (optional, default `80`)
- `options.force` **[Boolean][6]** force TIFF output, otherwise attempt to use input format (optional, default `true`)
- `options.compression` **[Boolean][6]** compression options: lzw, deflate, jpeg, ccittfax4 (optional, default `'jpeg'`)
- `options.predictor` **[Boolean][6]** compression predictor options: none, horizontal, float (optional, default `'horizontal'`)
- `options.pyramid` **[Boolean][6]** write an image pyramid (optional, default `false`)
- `options.tile` **[Boolean][6]** write a tiled tiff (optional, default `false`)
- `options.tileWidth` **[Boolean][6]** horizontal tile size (optional, default `256`)
- `options.tileHeight` **[Boolean][6]** vertical tile size (optional, default `256`)
- `options.xres` **[Number][8]** horizontal resolution in pixels/mm (optional, default `1.0`)
- `options.yres` **[Number][8]** vertical resolution in pixels/mm (optional, default `1.0`)
- `options.squash` **[Boolean][6]** squash 8-bit images down to 1 bit (optional, default `false`)
- `options` **[Object][6]?** output options
- `options.quality` **[Number][9]** quality, integer 1-100 (optional, default `80`)
- `options.force` **[Boolean][7]** force TIFF output, otherwise attempt to use input format (optional, default `true`)
- `options.compression` **[Boolean][7]** compression options: lzw, deflate, jpeg, ccittfax4 (optional, default `'jpeg'`)
- `options.predictor` **[Boolean][7]** compression predictor options: none, horizontal, float (optional, default `'horizontal'`)
- `options.pyramid` **[Boolean][7]** write an image pyramid (optional, default `false`)
- `options.tile` **[Boolean][7]** write a tiled tiff (optional, default `false`)
- `options.tileWidth` **[Boolean][7]** horizontal tile size (optional, default `256`)
- `options.tileHeight` **[Boolean][7]** vertical tile size (optional, default `256`)
- `options.xres` **[Number][9]** horizontal resolution in pixels/mm (optional, default `1.0`)
- `options.yres` **[Number][9]** vertical resolution in pixels/mm (optional, default `1.0`)
- `options.squash` **[Boolean][7]** squash 8-bit images down to 1 bit (optional, default `false`)
### Examples
@@ -234,7 +241,7 @@ sharp('input.svg')
.then(info => { ... });
```
- Throws **[Error][3]** Invalid options
- Throws **[Error][4]** Invalid options
Returns **Sharp**
@@ -251,13 +258,13 @@ Most versions of libheif support only the patent-encumbered HEVC compression for
### Parameters
- `options` **[Object][5]?** output options
- `options.quality` **[Number][8]** quality, integer 1-100 (optional, default `80`)
- `options.compression` **[Boolean][6]** compression format: hevc, avc, jpeg, av1 (optional, default `'hevc'`)
- `options.lossless` **[Boolean][6]** use lossless compression (optional, default `false`)
- `options` **[Object][6]?** output options
- `options.quality` **[Number][9]** quality, integer 1-100 (optional, default `80`)
- `options.compression` **[Boolean][7]** compression format: hevc, avc, jpeg, av1 (optional, default `'hevc'`)
- `options.lossless` **[Boolean][7]** use lossless compression (optional, default `false`)
- Throws **[Error][3]** Invalid options
- Throws **[Error][4]** Invalid options
Returns **Sharp**
@@ -282,8 +289,8 @@ Force output to a given format.
### Parameters
- `format` **([String][1] \| [Object][5])** as a String or an Object with an 'id' attribute
- `options` **[Object][5]** output options
- `format` **([String][2] \| [Object][6])** as a String or an Object with an 'id' attribute
- `options` **[Object][6]** output options
### Examples
@@ -294,7 +301,7 @@ const data = await sharp(input)
.toBuffer();
```
- Throws **[Error][3]** unsupported format or options
- Throws **[Error][4]** unsupported format or options
Returns **Sharp**
@@ -308,14 +315,14 @@ Warning: multiple sharp instances concurrently producing tile output can expose
### Parameters
- `options` **[Object][5]?**
- `options.size` **[Number][8]** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
- `options.overlap` **[Number][8]** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`)
- `options.angle` **[Number][8]** tile angle of rotation, must be a multiple of 90. (optional, default `0`)
- `options.depth` **[String][1]?** how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout.
- `options.skipBlanks` **[Number][8]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`)
- `options.container` **[String][1]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
- `options.layout` **[String][1]** filesystem layout, possible values are `dz`, `zoomify` or `google`. (optional, default `'dz'`)
- `options` **[Object][6]?**
- `options.size` **[Number][9]** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
- `options.overlap` **[Number][9]** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`)
- `options.angle` **[Number][9]** tile angle of rotation, must be a multiple of 90. (optional, default `0`)
- `options.depth` **[String][2]?** how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout.
- `options.skipBlanks` **[Number][9]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`)
- `options.container` **[String][2]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
- `options.layout` **[String][2]** filesystem layout, possible values are `dz`, `zoomify` or `google`. (optional, default `'dz'`)
### Examples
@@ -331,22 +338,24 @@ sharp('input.tiff')
});
```
- Throws **[Error][3]** Invalid parameters
- Throws **[Error][4]** Invalid parameters
Returns **Sharp**
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
[1]: #withmetadata
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
[7]: https://nodejs.org/api/buffer.html
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[8]: https://nodejs.org/api/buffer.html
[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

View File

@@ -4,6 +4,28 @@
Requires libvips v8.8.1.
#### v0.23.1 - 26<sup>th</sup> September 2019
* Ensure `sharp.format.vips` is present and correct (filesystem only).
[#1813](https://github.com/lovell/sharp/issues/1813)
* Ensure invalid `width` and `height` provided as options to `resize` throw.
[#1817](https://github.com/lovell/sharp/issues/1817)
* Allow use of 'heic' and 'heif' identifiers with `toFormat`.
[#1834](https://github.com/lovell/sharp/pull/1834)
[@jaubourg](https://github.com/jaubourg)
* Add `premultiplied` option to `composite` operation.
[#1835](https://github.com/lovell/sharp/pull/1835)
[@Andargor](https://github.com/Andargor)
* Allow instance reuse with differing `toBuffer` options.
[#1860](https://github.com/lovell/sharp/pull/1860)
[@RaboliotTheGrey](https://github.com/RaboliotTheGrey)
* Ensure image is at least 3x3 pixels before attempting trim operation.
#### v0.23.0 - 29<sup>th</sup> July 2019
* Remove `overlayWith` previously deprecated in v0.22.0.

View File

@@ -7,7 +7,8 @@ is to convert large images in common formats to
smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings.
quickest ImageMagick and GraphicsMagick settings
due to its use of [libvips](https://github.com/libvips/libvips).
Colour spaces, embedded ICC profiles and alpha transparency channels are all handled correctly.
Lanczos resampling ensures quality is not sacrificed for speed.
@@ -126,6 +127,7 @@ the help and code contributions of the following people:
* [Michael B. Klein](https://github.com/mbklein)
* [Jakub Michálek](https://github.com/Goues)
* [Ilya Ovdin](https://github.com/iovdin)
* [Andargor](https://github.com/Andargor)
Thank you!

View File

@@ -4,16 +4,15 @@
* AWS EC2 eu-west-1 [c5.large](https://aws.amazon.com/ec2/instance-types/c5/) (2x Xeon Platinum 8124M CPU @ 3.00GHz)
* Ubuntu 18.04 (hvm-ssd/ubuntu-bionic-18.04-amd64-server-20180912 ami-00035f41c82244dab)
* Node.js v10.11.0
* Node.js v12.10.0
### The contenders
* [jimp](https://www.npmjs.com/package/jimp) v0.5.3 - Image processing in pure JavaScript. Provides bicubic interpolation.
* [mapnik](https://www.npmjs.org/package/mapnik) v4.0.1 - Whilst primarily a map renderer, Mapnik contains bitmap image utilities.
* [imagemagick-native](https://www.npmjs.com/package/imagemagick-native) v1.9.3 - Wrapper around libmagick++, supports Buffers only.
* [jimp](https://www.npmjs.com/package/jimp) v0.8.4 - Image processing in pure JavaScript. Provides bicubic interpolation.
* [mapnik](https://www.npmjs.org/package/mapnik) v4.3.1 - Whilst primarily a map renderer, Mapnik contains bitmap image utilities.
* [imagemagick](https://www.npmjs.com/package/imagemagick) v0.1.3 - Supports filesystem only and "*has been unmaintained for a long time*".
* [gm](https://www.npmjs.com/package/gm) v1.23.1 - Fully featured wrapper around GraphicsMagick's `gm` command line utility.
* sharp v0.21.0 / libvips v8.7.0 - Caching within libvips disabled to ensure a fair comparison.
* sharp v0.23.1 / libvips v8.8.1 - Caching within libvips disabled to ensure a fair comparison.
### The task
@@ -25,14 +24,14 @@ then compress to JPEG at a "quality" setting of 80.
| Module | Input | Output | Ops/sec | Speed-up |
| :----------------- | :----- | :----- | ------: | -------: |
| jimp | buffer | buffer | 0.71 | 1.0 |
| mapnik | buffer | buffer | 3.32 | 4.7 |
| gm | buffer | buffer | 3.97 | 5.6 |
| imagemagick-native | buffer | buffer | 4.06 | 5.7 |
| imagemagick | file | file | 4.24 | 6.0 |
| sharp | stream | stream | 25.30 | 35.6 |
| sharp | file | file | 26.17 | 36.9 |
| sharp | buffer | buffer | 26.45 | 37.3 |
| jimp | buffer | buffer | 0.66 | 1.0 |
| mapnik | buffer | buffer | 3.31 | 5.0 |
| gm | buffer | buffer | 3.79 | 5.7 |
| gm | file | file | 3.82 | 5.8 |
| imagemagick | file | file | 4.17 | 6.3 |
| sharp | stream | stream | 25.81 | 39.1 |
| sharp | file | file | 26.76 | 40.5 |
| sharp | buffer | buffer | 28.06 | 42.5 |
Greater libvips performance can be expected with caching enabled (default)
and using 8+ core machines, especially those with larger L1/L2 CPU caches.

View File

@@ -20,15 +20,18 @@ function env (key) {
module.exports = function () {
try {
const proxy = url.parse(proxies.map(env).find(is.string));
const proxy = new url.URL(proxies.map(env).find(is.string));
const tunnel = proxy.protocol === 'https:'
? tunnelAgent.httpsOverHttps
: tunnelAgent.httpsOverHttp;
const proxyAuth = proxy.username && proxy.password
? `${proxy.username}:${proxy.password}`
: null;
return tunnel({
proxy: {
port: Number(proxy.port),
host: proxy.hostname,
proxyAuth: proxy.auth
proxyAuth
}
});
} catch (err) {

View File

@@ -83,18 +83,22 @@ function toColorspace (colorspace) {
* Update a colour attribute of the this.options Object.
* @private
* @param {String} key
* @param {String|Object} val
* @throws {Error} Invalid key
* @param {String|Object} value
* @throws {Error} Invalid value
*/
function _setColourOption (key, val) {
if (is.object(val) || is.string(val)) {
const colour = color(val);
this.options[key] = [
colour.red(),
colour.green(),
colour.blue(),
Math.round(colour.alpha() * 255)
];
function _setBackgroundColourOption (key, value) {
if (is.defined(value)) {
if (is.object(value) || is.string(value)) {
const colour = color(value);
this.options[key] = [
colour.red(),
colour.green(),
colour.blue(),
Math.round(colour.alpha() * 255)
];
} else {
throw is.invalidParameterError('background', 'object or string', value);
}
}
}
@@ -111,7 +115,7 @@ module.exports = function (Sharp) {
toColourspace,
toColorspace,
// Private
_setColourOption
_setBackgroundColourOption
});
// Class attributes
Sharp.colourspace = colourspace;

View File

@@ -81,6 +81,7 @@ const blend = {
* @param {Number} [images[].top] - the pixel offset from the top edge.
* @param {Number} [images[].left] - the pixel offset from the left edge.
* @param {Boolean} [images[].tile=false] - set to true to repeat the overlay image across the entire image with the given `gravity`.
* @param {Boolean} [images[].premultiplied=false] - set to true to avoid premultipling the image below. Equivalent to the `--premultiplied` vips option.
* @param {Number} [images[].density=72] - number representing the DPI for vector overlay image.
* @param {Object} [images[].raw] - describes overlay when using raw pixel data.
* @param {Number} [images[].raw.width]
@@ -105,7 +106,8 @@ function composite (images) {
tile: false,
left: -1,
top: -1,
gravity: 0
gravity: 0,
premultiplied: false
};
if (is.defined(image.blend)) {
if (is.string(blend[image.blend])) {
@@ -147,6 +149,14 @@ function composite (images) {
throw is.invalidParameterError('gravity', 'valid gravity', image.gravity);
}
}
if (is.defined(image.premultiplied)) {
if (is.bool(image.premultiplied)) {
composite.premultiplied = image.premultiplied;
} else {
throw is.invalidParameterError('premultiplied', 'boolean', image.premultiplied);
}
}
return composite;
});
return this;

View File

@@ -179,7 +179,7 @@ function blur (sigma) {
function flatten (options) {
this.options.flatten = is.bool(options) ? options : true;
if (is.object(options)) {
this._setColourOption('flattenBackground', options.background);
this._setBackgroundColourOption('flattenBackground', options.background);
}
return this;
}

View File

@@ -10,6 +10,9 @@ const sharp = require('../build/Release/sharp.node');
* with JPEG, PNG, WebP, TIFF, DZI, and libvips' V format supported.
* Note that raw pixel data is only supported for buffer output.
*
* By default all metadata will be removed, which includes EXIF-based orientation.
* See {@link withMetadata} for control over this.
*
* A `Promise` is returned when `callback` is not provided.
*
* @example
@@ -57,7 +60,11 @@ function toFile (fileOut, callback) {
/**
* Write output to a Buffer.
* JPEG, PNG, WebP, TIFF and RAW output are supported.
* By default, the format will match the input image, except GIF and SVG input which become PNG output.
*
* If no explicit format is set, the output format will match the input image, except GIF and SVG input which become PNG output.
*
* By default all metadata will be removed, which includes EXIF-based orientation.
* See {@link withMetadata} for control over this.
*
* `callback`, if present, gets three arguments `(err, data, info)` where:
* - `err` is an error, if any.
@@ -92,6 +99,8 @@ function toFile (fileOut, callback) {
function toBuffer (options, callback) {
if (is.object(options)) {
this._setBooleanOption('resolveWithObject', options.resolveWithObject);
} else if (this.options.resolveWithObject) {
this.options.resolveWithObject = false;
}
return this._pipeline(is.fn(options) ? options : callback);
}
@@ -487,6 +496,17 @@ function raw () {
return this._updateFormatOut('raw');
}
const formats = new Map([
['heic', 'heif'],
['heif', 'heif'],
['jpeg', 'jpeg'],
['jpg', 'jpeg'],
['png', 'png'],
['raw', 'raw'],
['tiff', 'tiff'],
['webp', 'webp']
]);
/**
* Force output to a given format.
*
@@ -502,14 +522,11 @@ function raw () {
* @throws {Error} unsupported format or options
*/
function toFormat (format, options) {
if (is.object(format) && is.string(format.id)) {
format = format.id;
const actualFormat = formats.get(is.object(format) && is.string(format.id) ? format.id : format);
if (!actualFormat) {
throw is.invalidParameterError('format', `one of: ${[...formats.keys()].join(', ')}`, format);
}
if (format === 'jpg') format = 'jpeg';
if (!is.inArray(format, ['jpeg', 'png', 'webp', 'tiff', 'raw'])) {
throw is.invalidParameterError('format', 'one of: jpeg, png, webp, tiff, raw', format);
}
return this[format](options);
return this[actualFormat](options);
}
/**

View File

@@ -7,6 +7,7 @@ const env = process.env;
module.exports = function () {
const arch = env.npm_config_arch || process.arch;
const platform = env.npm_config_platform || process.platform;
/* istanbul ignore next */
const libc = (platform === 'linux' && detectLibc.isNonGlibcLinux) ? detectLibc.family : '';
const platformId = [`${platform}${libc}`];

View File

@@ -210,12 +210,20 @@ function resize (width, height, options) {
}
if (is.object(options)) {
// Width
if (is.integer(options.width) && options.width > 0) {
this.options.width = options.width;
if (is.defined(options.width)) {
if (is.integer(options.width) && options.width > 0) {
this.options.width = options.width;
} else {
throw is.invalidParameterError('width', 'positive integer', options.width);
}
}
// Height
if (is.integer(options.height) && options.height > 0) {
this.options.height = options.height;
if (is.defined(options.height)) {
if (is.integer(options.height) && options.height > 0) {
this.options.height = options.height;
} else {
throw is.invalidParameterError('height', 'positive integer', options.height);
}
}
// Fit
if (is.defined(options.fit)) {
@@ -239,7 +247,7 @@ function resize (width, height, options) {
}
// Background
if (is.defined(options.background)) {
this._setColourOption('resizeBackground', options.background);
this._setBackgroundColourOption('resizeBackground', options.background);
}
// Kernel
if (is.defined(options.kernel)) {
@@ -305,7 +313,7 @@ function extend (extend) {
this.options.extendBottom = extend.bottom;
this.options.extendLeft = extend.left;
this.options.extendRight = extend.right;
this._setColourOption('extendBackground', extend.background);
this._setBackgroundColourOption('extendBackground', extend.background);
} else {
throw is.invalidParameterError('extend', 'integer or object', extend);
}

View File

@@ -1,7 +1,7 @@
{
"name": "sharp",
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
"version": "0.23.0",
"version": "0.23.1",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://github.com/lovell/sharp",
"contributors": [
@@ -61,7 +61,8 @@
"Keith Belovay <keith@picthrive.com>",
"Michael B. Klein <mbklein@gmail.com>",
"Jordan Prudhomme <jordan@raboland.fr>",
"Ilya Ovdin <iovdin@gmail.com>"
"Ilya Ovdin <iovdin@gmail.com>",
"Andargor <andargor@yahoo.com>"
],
"scripts": {
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
@@ -99,27 +100,27 @@
"detect-libc": "^1.0.3",
"nan": "^2.14.0",
"npmlog": "^4.1.2",
"prebuild-install": "^5.3.0",
"prebuild-install": "^5.3.2",
"semver": "^6.3.0",
"simple-get": "^3.0.3",
"tar": "^4.4.10",
"simple-get": "^3.1.0",
"tar": "^4.4.13",
"tunnel-agent": "^0.6.0"
},
"devDependencies": {
"async": "^3.1.0",
"cc": "^1.0.2",
"decompress-zip": "^0.3.2",
"documentation": "^12.0.3",
"documentation": "^12.1.2",
"exif-reader": "^1.0.2",
"icc": "^1.0.0",
"license-checker": "^25.0.1",
"mocha": "^6.2.0",
"mock-fs": "^4.10.1",
"nyc": "^14.1.1",
"prebuild": "^9.0.1",
"prebuild": "^9.1.0",
"prebuild-ci": "^3.1.0",
"rimraf": "^2.6.3",
"semistandard": "^13.0.1"
"rimraf": "^3.0.0",
"semistandard": "^14.2.0"
},
"license": "Apache-2.0",
"config": {

View File

@@ -147,7 +147,7 @@ namespace sharp {
case ImageType::OPENSLIDE: id = "openslide"; break;
case ImageType::PPM: id = "ppm"; break;
case ImageType::FITS: id = "fits"; break;
case ImageType::VIPS: id = "v"; break;
case ImageType::VIPS: id = "vips"; break;
case ImageType::RAW: id = "raw"; break;
case ImageType::UNKNOWN: id = "unknown"; break;
case ImageType::MISSING: id = "missing"; break;

View File

@@ -250,6 +250,9 @@ namespace sharp {
Trim an image
*/
VImage Trim(VImage image, double const threshold) {
if (image.width() < 3 && image.height() < 3) {
throw VError("Image to trim must be at least 3x3 pixels");
}
// Top-left pixel provides the background colour
VImage background = image.extract_area(0, 0, 1, 1);
if (HasAlpha(background)) {

View File

@@ -591,7 +591,7 @@ class PipelineWorker : public Nan::AsyncWorker {
if (!HasAlpha(compositeImage)) {
compositeImage = sharp::EnsureAlpha(compositeImage);
}
compositeImage = compositeImage.premultiply();
if (!composite->premultiplied) compositeImage = compositeImage.premultiply();
// Calculate position
int left;
int top;
@@ -1230,6 +1230,7 @@ NAN_METHOD(pipeline) {
composite->left = AttrTo<int32_t>(compositeObject, "left");
composite->top = AttrTo<int32_t>(compositeObject, "top");
composite->tile = AttrTo<bool>(compositeObject, "tile");
composite->premultiplied = AttrTo<bool>(compositeObject, "premultiplied");
baton->composite.push_back(composite);
}
// Resize options

View File

@@ -41,6 +41,7 @@ struct Composite {
int left;
int top;
bool tile;
bool premultiplied;
Composite():
input(nullptr),
@@ -48,7 +49,8 @@ struct Composite {
gravity(0),
left(-1),
top(-1),
tile(false) {}
tile(false),
premultiplied(false) {}
};
struct PipelineBaton {

View File

@@ -150,8 +150,9 @@ NAN_METHOD(format) {
// Which load/save operations are available for each compressed format?
Local<Object> format = New<Object>();
for (std::string f : {
"jpeg", "png", "webp", "tiff", "magick", "openslide", "dz", "ppm", "fits", "gif", "svg", "heif", "pdf", "v"
for (std::string const f : {
"jpeg", "png", "webp", "tiff", "magick", "openslide", "dz",
"ppm", "fits", "gif", "svg", "heif", "pdf", "vips"
}) {
// Input
Local<Boolean> hasInputFile =

View File

@@ -12,10 +12,9 @@
"benchmark": "^2.1.4",
"gm": "^1.23.1",
"imagemagick": "^0.1.3",
"imagemagick-native": "^1.9.3",
"jimp": "^0.6.4",
"mapnik": "^4.2.1",
"semver": "^6.1.2"
"jimp": "^0.8.4",
"mapnik": "^4.3.1",
"semver": "^6.3.0"
},
"license": "Apache-2.0",
"engines": {

View File

@@ -12,12 +12,6 @@ const gm = require('gm');
const imagemagick = require('imagemagick');
const mapnik = require('mapnik');
const jimp = require('jimp');
let imagemagickNative;
try {
imagemagickNative = require('imagemagick-native');
} catch (err) {
console.log('Excluding imagemagick-native');
}
const fixtures = require('../fixtures');
@@ -28,7 +22,7 @@ const height = 588;
sharp.cache(false);
async.series({
'jpeg': function (callback) {
jpeg: function (callback) {
const inputJpgBuffer = fs.readFileSync(fixtures.inputJpg);
const jpegSuite = new Benchmark.Suite('jpeg');
// jimp
@@ -126,29 +120,6 @@ async.series({
});
}
});
// imagemagick-native
if (typeof imagemagickNative !== 'undefined') {
jpegSuite.add('imagemagick-native-buffer-buffer', {
defer: true,
fn: function (deferred) {
imagemagickNative.convert({
srcData: inputJpgBuffer,
quality: 80,
width: width,
height: height,
format: 'JPEG',
filter: 'Lanczos'
}, function (err, buffer) {
if (err) {
throw err;
} else {
assert.notStrictEqual(null, buffer);
deferred.resolve();
}
});
}
});
}
// gm
jpegSuite.add('gm-buffer-file', {
defer: true,
@@ -289,6 +260,9 @@ async.series({
.then(function (buffer) {
assert.notStrictEqual(null, buffer);
deferred.resolve();
})
.catch(function (err) {
throw err;
});
}
}).on('cycle', function (event) {
@@ -698,22 +672,6 @@ async.series({
});
}
});
// imagemagick-native
if (typeof imagemagickNative !== 'undefined') {
pngSuite.add('imagemagick-native-buffer-buffer', {
defer: true,
fn: function (deferred) {
imagemagickNative.convert({
srcData: inputPngBuffer,
width: width,
height: height,
format: 'PNG',
filter: 'Lanczos'
});
deferred.resolve();
}
});
}
// gm
pngSuite.add('gm-file-file', {
defer: true,

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 839 B

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -54,7 +54,7 @@ describe('Alpha transparency', function () {
assert.strictEqual(true, info.size > 0);
assert.strictEqual(32, info.width);
assert.strictEqual(32, info.height);
fixtures.assertMaxColourDistance(output, fixtures.expected('flatten-rgb16-orange.jpg'), 25);
fixtures.assertMaxColourDistance(output, fixtures.expected('flatten-rgb16-orange.jpg'), 10);
done();
});
});
@@ -81,6 +81,18 @@ describe('Alpha transparency', function () {
});
});
it('Flatten with options but without colour does not throw', () => {
assert.doesNotThrow(() => {
sharp().flatten({});
});
});
it('Flatten to invalid colour throws', () => {
assert.throws(() => {
sharp().flatten({ background: 1 });
});
});
it('Enlargement with non-nearest neighbor interpolation shouldnt cause dark edges', function () {
const base = 'alpha-premultiply-enlargement-2048x1536-paper.png';
const actual = fixtures.path('output.' + base);

View File

@@ -62,6 +62,65 @@ describe('composite', () => {
})
));
it('premultiplied true', () => {
const filename = 'composite.premultiplied.png';
const below = fixtures.path(`input.below.${filename}`);
const above = fixtures.path(`input.above.${filename}`);
const actual = fixtures.path(`output.true.${filename}`);
const expected = fixtures.expected(`expected.true.${filename}`);
return sharp(below)
.composite([{
input: above,
blend: 'color-burn',
top: 0,
left: 0,
premultiplied: true
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
});
it('premultiplied false', () => {
const filename = 'composite.premultiplied.png';
const below = fixtures.path(`input.below.${filename}`);
const above = fixtures.path(`input.above.${filename}`);
const actual = fixtures.path(`output.false.${filename}`);
const expected = fixtures.expected(`expected.false.${filename}`);
return sharp(below)
.composite([{
input: above,
blend: 'color-burn',
top: 0,
left: 0,
premultiplied: false
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
});
it('premultiplied absent', () => {
const filename = 'composite.premultiplied.png';
const below = fixtures.path(`input.below.${filename}`);
const above = fixtures.path(`input.above.${filename}`);
const actual = fixtures.path(`output.absent.${filename}`);
const expected = fixtures.expected(`expected.absent.${filename}`);
return sharp(below)
.composite([{
input: above,
blend: 'color-burn',
top: 0,
left: 0
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
});
it('multiple', () => {
const filename = 'composite-multiple.png';
const actual = fixtures.path(`output.${filename}`);
@@ -265,6 +324,12 @@ describe('composite', () => {
}, /Expected boolean for tile but received invalid of type string/);
});
it('invalid premultiplied', () => {
assert.throws(() => {
sharp().composite([{ input: 'test', premultiplied: 'invalid' }]);
}, /Expected boolean for premultiplied but received invalid of type string/);
});
it('invalid left', () => {
assert.throws(() => {
sharp().composite([{ input: 'test', left: 0.5 }]);

View File

@@ -73,7 +73,7 @@ describe('Linear adjustment', function () {
assert.throws(function () {
sharp(fixtures.inputPngOverlayLayer1)
.linear(undefined, { 'bar': 'baz' });
.linear(undefined, { bar: 'baz' });
});
});
});

View File

@@ -232,6 +232,26 @@ describe('Image metadata', function () {
done();
});
});
it('vips', () =>
sharp(fixtures.inputV)
.metadata()
.then(metadata => {
assert.strictEqual('vips', metadata.format);
assert.strictEqual('undefined', typeof metadata.size);
assert.strictEqual(70, metadata.width);
assert.strictEqual(60, metadata.height);
assert.strictEqual(3, metadata.channels);
assert.strictEqual('uchar', metadata.depth);
assert.strictEqual(72, metadata.density);
assert.strictEqual('undefined', typeof metadata.chromaSubsampling);
assert.strictEqual(false, metadata.isProgressive);
assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual('undefined', typeof metadata.orientation);
assert.strictEqual('undefined', typeof metadata.exif);
assert.strictEqual('undefined', typeof metadata.icc);
})
);
it('File in, Promise out', function (done) {
sharp(fixtures.inputJpg).metadata().then(function (metadata) {

View File

@@ -53,7 +53,8 @@ describe('Raw pixel data', function () {
width: info.width,
height: info.height,
channels: info.channels
} })
}
})
.jpeg()
.toBuffer(function (err, data, info) {
if (err) throw err;
@@ -81,7 +82,8 @@ describe('Raw pixel data', function () {
width: info.width,
height: info.height,
channels: info.channels
} })
}
})
.png()
.toBuffer(function (err, data, info) {
if (err) throw err;

View File

@@ -87,6 +87,18 @@ describe('Resize dimensions', function () {
}, /Expected positive integer for height but received 1.5 of type number/);
});
it('Invalid width - via options', () => {
assert.throws(() => {
sharp().resize({ width: 1.5, height: 240 });
}, /Expected positive integer for width but received 1.5 of type number/);
});
it('Invalid height - via options', () => {
assert.throws(() => {
sharp().resize({ width: 320, height: 1.5 });
}, /Expected positive integer for height but received 1.5 of type number/);
});
it('Invalid width - too large', function (done) {
sharp(fixtures.inputJpg)
.resize(0x4000, 1)

View File

@@ -27,52 +27,52 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
// green channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[1]['minX']));
assert.strictEqual(true, isInRange(stats.channels[1]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1]['minY']));
assert.strictEqual(true, isInRange(stats.channels[1]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
assert.strictEqual(true, isInRange(stats.channels[1].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1].maxX));
assert.strictEqual(true, isInRange(stats.channels[1].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1].maxY));
assert.strictEqual(true, isInRange(stats.channels[1].maxY, 0, 2725));
// blue channel
assert.strictEqual(0, stats.channels[2]['min']);
assert.strictEqual(255, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[2]['minX']));
assert.strictEqual(true, isInRange(stats.channels[2]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2]['minY']));
assert.strictEqual(true, isInRange(stats.channels[2]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[2].min);
assert.strictEqual(255, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[2].minX));
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2].minY));
assert.strictEqual(true, isInRange(stats.channels[2].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2].maxX));
assert.strictEqual(true, isInRange(stats.channels[2].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2].maxY));
assert.strictEqual(true, isInRange(stats.channels[2].maxY, 0, 2725));
done();
});
@@ -86,20 +86,20 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 0.3409031108021736));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 1391368230));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 354798898650));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 238.8259925648822));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 62.15121915523771));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2809));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2074));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2809));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2074));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 1391368230));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 354798898650));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 238.8259925648822));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 62.15121915523771));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2809));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2074));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2809));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2074));
done();
});
});
@@ -112,68 +112,68 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 0.06778064835816622));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 795678795));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 202898092725));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 252.9394769668579));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 22.829537532816));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 1536));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 795678795));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 202898092725));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 252.9394769668579));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 22.829537532816));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 1536));
// green channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 795678795));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 202898092725));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 252.9394769668579));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 22.829537532816));
assert.strictEqual(true, isInteger(stats.channels[1]['minX']));
assert.strictEqual(true, isInRange(stats.channels[1]['minX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[1]['minY']));
assert.strictEqual(true, isInRange(stats.channels[1]['minY'], 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[1]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[1]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxY'], 0, 1536));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 795678795));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 202898092725));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 252.9394769668579));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 22.829537532816));
assert.strictEqual(true, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
assert.strictEqual(true, isInRange(stats.channels[1].minY, 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[1].maxX));
assert.strictEqual(true, isInRange(stats.channels[1].maxX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[1].maxY));
assert.strictEqual(true, isInRange(stats.channels[1].maxY, 0, 1536));
// blue channel
assert.strictEqual(0, stats.channels[2]['min']);
assert.strictEqual(255, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 795678795));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 202898092725));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 252.9394769668579));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 22.829537532816));
assert.strictEqual(true, isInteger(stats.channels[2]['minX']));
assert.strictEqual(true, isInRange(stats.channels[2]['minX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[2]['minY']));
assert.strictEqual(true, isInRange(stats.channels[2]['minY'], 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[2]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[2]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxY'], 0, 1536));
assert.strictEqual(0, stats.channels[2].min);
assert.strictEqual(255, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 795678795));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 202898092725));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 252.9394769668579));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 22.829537532816));
assert.strictEqual(true, isInteger(stats.channels[2].minX));
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[2].minY));
assert.strictEqual(true, isInRange(stats.channels[2].minY, 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[2].maxX));
assert.strictEqual(true, isInRange(stats.channels[2].maxX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[2].maxY));
assert.strictEqual(true, isInRange(stats.channels[2].maxY, 0, 1536));
// alpha channel
assert.strictEqual(0, stats.channels[3]['min']);
assert.strictEqual(255, stats.channels[3]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['sum'], 5549142));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['squaresSum'], 1333571132));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['mean'], 1.7640247344970703));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['stdev'], 20.51387814157297));
assert.strictEqual(true, isInteger(stats.channels[3]['minX']));
assert.strictEqual(true, isInRange(stats.channels[3]['minX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[3]['minY']));
assert.strictEqual(true, isInRange(stats.channels[3]['minY'], 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[3]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[3]['maxX'], 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[3]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[3]['maxY'], 0, 1536));
assert.strictEqual(0, stats.channels[3].min);
assert.strictEqual(255, stats.channels[3].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].sum, 5549142));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].squaresSum, 1333571132));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].mean, 1.7640247344970703));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].stdev, 20.51387814157297));
assert.strictEqual(true, isInteger(stats.channels[3].minX));
assert.strictEqual(true, isInRange(stats.channels[3].minX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[3].minY));
assert.strictEqual(true, isInRange(stats.channels[3].minY, 0, 1536));
assert.strictEqual(true, isInteger(stats.channels[3].maxX));
assert.strictEqual(true, isInRange(stats.channels[3].maxX, 0, 2048));
assert.strictEqual(true, isInteger(stats.channels[3].maxY));
assert.strictEqual(true, isInRange(stats.channels[3].maxY, 0, 1536));
done();
});
@@ -187,20 +187,20 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 0));
// alpha channel
assert.strictEqual(0, stats.channels[3]['min']);
assert.strictEqual(0, stats.channels[3]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['sum'], 0));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['squaresSum'], 0));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['mean'], 0));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3]['stdev'], 0));
assert.strictEqual(true, isInteger(stats.channels[3]['minX']));
assert.strictEqual(true, isInRange(stats.channels[3]['minX'], 0, 300));
assert.strictEqual(true, isInteger(stats.channels[3]['minY']));
assert.strictEqual(true, isInRange(stats.channels[3]['minY'], 0, 300));
assert.strictEqual(true, isInteger(stats.channels[3]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[3]['maxX'], 0, 300));
assert.strictEqual(true, isInteger(stats.channels[3]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[3]['maxY'], 0, 300));
assert.strictEqual(0, stats.channels[3].min);
assert.strictEqual(0, stats.channels[3].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].sum, 0));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].squaresSum, 0));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].mean, 0));
assert.strictEqual(true, isInAcceptableRange(stats.channels[3].stdev, 0));
assert.strictEqual(true, isInteger(stats.channels[3].minX));
assert.strictEqual(true, isInRange(stats.channels[3].minX, 0, 300));
assert.strictEqual(true, isInteger(stats.channels[3].minY));
assert.strictEqual(true, isInRange(stats.channels[3].minY, 0, 300));
assert.strictEqual(true, isInteger(stats.channels[3].maxX));
assert.strictEqual(true, isInRange(stats.channels[3].maxX, 0, 300));
assert.strictEqual(true, isInteger(stats.channels[3].maxY));
assert.strictEqual(true, isInRange(stats.channels[3].maxY, 0, 300));
done();
});
@@ -214,20 +214,20 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 0.3851250782608986));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 1887266220));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 481252886100));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 235.81772349417824));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 67.25712856093298));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2464));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 3248));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2464));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 3248));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 1887266220));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 481252886100));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 235.81772349417824));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 67.25712856093298));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2464));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 3248));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2464));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 3248));
done();
});
@@ -241,52 +241,52 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.51758075132966));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 83291370));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 11379783198));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 105.36169496842616));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 57.39412151419967));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 772));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 772));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 83291370));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 11379783198));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 105.36169496842616));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 57.39412151419967));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 772));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 772));
// green channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 120877425));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 20774687595));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 152.9072025279307));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 53.84143349689916));
assert.strictEqual(true, isInteger(stats.channels[1]['minX']));
assert.strictEqual(true, isInRange(stats.channels[1]['minX'], 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[1]['minY']));
assert.strictEqual(true, isInRange(stats.channels[1]['minY'], 0, 772));
assert.strictEqual(true, isInteger(stats.channels[1]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxX'], 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[1]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxY'], 0, 772));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 120877425));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 20774687595));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 152.9072025279307));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 53.84143349689916));
assert.strictEqual(true, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
assert.strictEqual(true, isInRange(stats.channels[1].minY, 0, 772));
assert.strictEqual(true, isInteger(stats.channels[1].maxX));
assert.strictEqual(true, isInRange(stats.channels[1].maxX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[1].maxY));
assert.strictEqual(true, isInRange(stats.channels[1].maxY, 0, 772));
// blue channel
assert.strictEqual(0, stats.channels[2]['min']);
assert.strictEqual(255, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 138938859));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 28449125593));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 175.75450711423252));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 71.39929031070358));
assert.strictEqual(true, isInteger(stats.channels[2]['minX']));
assert.strictEqual(true, isInRange(stats.channels[2]['minX'], 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[2]['minY']));
assert.strictEqual(true, isInRange(stats.channels[2]['minY'], 0, 772));
assert.strictEqual(true, isInteger(stats.channels[2]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxX'], 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[2]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxY'], 0, 772));
assert.strictEqual(0, stats.channels[2].min);
assert.strictEqual(255, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 138938859));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 28449125593));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 175.75450711423252));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 71.39929031070358));
assert.strictEqual(true, isInteger(stats.channels[2].minX));
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[2].minY));
assert.strictEqual(true, isInRange(stats.channels[2].minY, 0, 772));
assert.strictEqual(true, isInteger(stats.channels[2].maxX));
assert.strictEqual(true, isInRange(stats.channels[2].maxX, 0, 1024));
assert.strictEqual(true, isInteger(stats.channels[2].maxY));
assert.strictEqual(true, isInRange(stats.channels[2].maxY, 0, 772));
done();
});
@@ -300,52 +300,52 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 6.087309412541799));
// red channel
assert.strictEqual(35, stats.channels[0]['min']);
assert.strictEqual(254, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 56088385));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 8002132113));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 131.53936444652908));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 38.26389131415863));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 800));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 533));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 800));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 533));
assert.strictEqual(35, stats.channels[0].min);
assert.strictEqual(254, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 56088385));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 8002132113));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 131.53936444652908));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 38.26389131415863));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 800));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 533));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 800));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 533));
// green channel
assert.strictEqual(43, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 58612156));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 8548344254));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 137.45815196998123));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 33.955424103758205));
assert.strictEqual(true, isInteger(stats.channels[1]['minX']));
assert.strictEqual(true, isInRange(stats.channels[1]['minX'], 0, 800));
assert.strictEqual(true, isInteger(stats.channels[1]['minY']));
assert.strictEqual(true, isInRange(stats.channels[1]['minY'], 0, 533));
assert.strictEqual(true, isInteger(stats.channels[1]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxX'], 0, 800));
assert.strictEqual(true, isInteger(stats.channels[1]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxY'], 0, 533));
assert.strictEqual(43, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 58612156));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 8548344254));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 137.45815196998123));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 33.955424103758205));
assert.strictEqual(true, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 800));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
assert.strictEqual(true, isInRange(stats.channels[1].minY, 0, 533));
assert.strictEqual(true, isInteger(stats.channels[1].maxX));
assert.strictEqual(true, isInRange(stats.channels[1].maxX, 0, 800));
assert.strictEqual(true, isInteger(stats.channels[1].maxY));
assert.strictEqual(true, isInRange(stats.channels[1].maxY, 0, 533));
// blue channel
assert.strictEqual(51, stats.channels[2]['min']);
assert.strictEqual(254, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 49628525));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 6450556071));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 116.38959896810506));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 39.7669551046809));
assert.strictEqual(true, isInteger(stats.channels[2]['minX']));
assert.strictEqual(true, isInRange(stats.channels[2]['minX'], 0, 800));
assert.strictEqual(true, isInteger(stats.channels[2]['minY']));
assert.strictEqual(true, isInRange(stats.channels[2]['minY'], 0, 533));
assert.strictEqual(true, isInteger(stats.channels[2]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxX'], 0, 800));
assert.strictEqual(true, isInteger(stats.channels[2]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxY'], 0, 533));
assert.strictEqual(51, stats.channels[2].min);
assert.strictEqual(254, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 49628525));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 6450556071));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 116.38959896810506));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 39.7669551046809));
assert.strictEqual(true, isInteger(stats.channels[2].minX));
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 800));
assert.strictEqual(true, isInteger(stats.channels[2].minY));
assert.strictEqual(true, isInRange(stats.channels[2].minY, 0, 533));
assert.strictEqual(true, isInteger(stats.channels[2].maxX));
assert.strictEqual(true, isInRange(stats.channels[2].maxX, 0, 800));
assert.strictEqual(true, isInteger(stats.channels[2].maxY));
assert.strictEqual(true, isInRange(stats.channels[2].maxY, 0, 533));
done();
});
@@ -359,36 +359,36 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 1));
// gray channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(101, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 101));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 10201));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 50.5));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 71.4177848998413));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 1));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 1));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(101, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 101));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 10201));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 50.5));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 71.4177848998413));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 1));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 1));
// alpha channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 65025));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 127.5));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 180.31222920256963));
assert.strictEqual(true, isInteger(stats.channels[1]['minX']));
assert.strictEqual(true, isInRange(stats.channels[1]['minX'], 0, 2));
assert.strictEqual(true, isInteger(stats.channels[1]['minY']));
assert.strictEqual(true, isInRange(stats.channels[1]['minY'], 0, 1));
assert.strictEqual(true, isInteger(stats.channels[1]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxX'], 0, 2));
assert.strictEqual(true, isInteger(stats.channels[1]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxY'], 0, 1));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 65025));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 127.5));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 180.31222920256963));
assert.strictEqual(true, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 2));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
assert.strictEqual(true, isInRange(stats.channels[1].minY, 0, 1));
assert.strictEqual(true, isInteger(stats.channels[1].maxX));
assert.strictEqual(true, isInRange(stats.channels[1].maxX, 0, 2));
assert.strictEqual(true, isInteger(stats.channels[1].maxY));
assert.strictEqual(true, isInRange(stats.channels[1].maxY, 0, 1));
done();
});
@@ -412,52 +412,52 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
// green channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[1]['minX']));
assert.strictEqual(true, isInRange(stats.channels[1]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1]['minY']));
assert.strictEqual(true, isInRange(stats.channels[1]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[1]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[1].minX));
assert.strictEqual(true, isInRange(stats.channels[1].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1].minY));
assert.strictEqual(true, isInRange(stats.channels[1].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1].maxX));
assert.strictEqual(true, isInRange(stats.channels[1].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[1].maxY));
assert.strictEqual(true, isInRange(stats.channels[1].maxY, 0, 2725));
// blue channel
assert.strictEqual(0, stats.channels[2]['min']);
assert.strictEqual(255, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[2]['minX']));
assert.strictEqual(true, isInRange(stats.channels[2]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2]['minY']));
assert.strictEqual(true, isInRange(stats.channels[2]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[2]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[2].min);
assert.strictEqual(255, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[2].minX));
assert.strictEqual(true, isInRange(stats.channels[2].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2].minY));
assert.strictEqual(true, isInRange(stats.channels[2].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2].maxX));
assert.strictEqual(true, isInRange(stats.channels[2].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[2].maxY));
assert.strictEqual(true, isInRange(stats.channels[2].maxY, 0, 2725));
done();
});
@@ -474,52 +474,52 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
// green channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
// blue channel
assert.strictEqual(0, stats.channels[2]['min']);
assert.strictEqual(255, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[2].min);
assert.strictEqual(255, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
}).catch(function (err) {
throw err;
});
@@ -531,52 +531,52 @@ describe('Image Stats', function () {
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
// red channel
assert.strictEqual(0, stats.channels[0]['min']);
assert.strictEqual(255, stats.channels[0]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['sum'], 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[0].min);
assert.strictEqual(255, stats.channels[0].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].sum, 615101275));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].squaresSum, 83061892917));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].mean, 101.44954540768993));
assert.strictEqual(true, isInAcceptableRange(stats.channels[0].stdev, 58.373870588815414));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
// green channel
assert.strictEqual(0, stats.channels[1]['min']);
assert.strictEqual(255, stats.channels[1]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['sum'], 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['squaresSum'], 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['mean'], 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1]['stdev'], 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[1].min);
assert.strictEqual(255, stats.channels[1].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].sum, 462824115));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].squaresSum, 47083677255));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].mean, 76.33425255128337));
assert.strictEqual(true, isInAcceptableRange(stats.channels[1].stdev, 44.03023262954866));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
// blue channel
assert.strictEqual(0, stats.channels[2]['min']);
assert.strictEqual(255, stats.channels[2]['max']);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['sum'], 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['squaresSum'], 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['mean'], 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2]['stdev'], 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[0]['minX']));
assert.strictEqual(true, isInRange(stats.channels[0]['minX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['minY']));
assert.strictEqual(true, isInRange(stats.channels[0]['minY'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxX']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxX'], 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0]['maxY']));
assert.strictEqual(true, isInRange(stats.channels[0]['maxY'], 0, 2725));
assert.strictEqual(0, stats.channels[2].min);
assert.strictEqual(255, stats.channels[2].max);
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].sum, 372986756));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].squaresSum, 32151543524));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].mean, 61.51724663436759));
assert.strictEqual(true, isInAcceptableRange(stats.channels[2].stdev, 38.96702865090125));
assert.strictEqual(true, isInteger(stats.channels[0].minX));
assert.strictEqual(true, isInRange(stats.channels[0].minX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].minY));
assert.strictEqual(true, isInRange(stats.channels[0].minY, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxX));
assert.strictEqual(true, isInRange(stats.channels[0].maxX, 0, 2725));
assert.strictEqual(true, isInteger(stats.channels[0].maxY));
assert.strictEqual(true, isInRange(stats.channels[0].maxY, 0, 2725));
}).catch(function (err) {
throw err;
});

View File

@@ -56,7 +56,7 @@ const assertZoomifyTiles = function (directory, expectedTileSize, expectedLevels
fs.readdirSync(path.join(directory, 'TileGroup0')).forEach(function (tile) {
// Verify tile file name
assert.ok(/^[0-9]+-[0-9]+-[0-9]+\.jpg$/.test(tile));
let level = parseInt(tile.split('-')[0]);
const level = parseInt(tile.split('-')[0]);
maxTileLevel = Math.max(maxTileLevel, level);
});
@@ -319,7 +319,7 @@ describe('Tile', function () {
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');
const 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
@@ -396,7 +396,7 @@ describe('Tile', function () {
if (err) throw err;
// assert them 0_0.jpeg doesn't exist because it's a white tile
const whiteTilePath = path.join(directory, '11', '0_0.jpeg');
assert.strictEqual(fs.existsSync(whiteTilePath), false, `Tile shouldn't exist`);
assert.strictEqual(fs.existsSync(whiteTilePath), false, 'Tile should not exist');
// Verify only one depth generated
assertDeepZoomTiles(directory, 256, 12, done);
});
@@ -503,7 +503,7 @@ describe('Tile', function () {
if (err) throw err;
// assert them 0_0.jpeg doesn't exist because it's a white tile
const whiteTilePath = path.join(directory, 'TileGroup0', '2-0-0.jpg');
assert.strictEqual(fs.existsSync(whiteTilePath), false, `Tile shouldn't exist`);
assert.strictEqual(fs.existsSync(whiteTilePath), false, 'Tile should not exist');
assert.strictEqual('dz', info.format);
assert.strictEqual(2048, info.width);
assert.strictEqual(1536, info.height);
@@ -727,7 +727,7 @@ describe('Tile', function () {
if (err) throw err;
const whiteTilePath = path.join(directory, '4', '8', '0.jpg');
assert.strictEqual(fs.existsSync(whiteTilePath), false, `Tile shouldn't exist`);
assert.strictEqual(fs.existsSync(whiteTilePath), false, 'Tile should not exist');
assert.strictEqual('dz', info.format);
assert.strictEqual(2809, info.width);

19
test/unit/toBuffer.js Normal file
View File

@@ -0,0 +1,19 @@
'use strict';
const assert = require('assert');
const sharp = require('../../');
const fixtures = require('../fixtures');
describe('toBuffer', () => {
it('reusing same sharp object does not reset previously passed parameters to toBuffer', (done) => {
const image = sharp(fixtures.inputJpg);
image.toBuffer({ resolveWithObject: true }).then((obj) => {
image.toBuffer().then((buff) => {
assert.strict.equal(Buffer.isBuffer(buff), true);
assert.strict.equal(typeof obj, 'object');
done();
});
});
});
});

View File

@@ -58,6 +58,27 @@ describe('Trim borders', function () {
});
});
it('Attempt to trim 2x2 pixel image fails', function (done) {
sharp({
create: {
width: 2,
height: 2,
channels: 3,
background: 'red'
}
})
.trim()
.toBuffer()
.then(() => {
done(new Error('Expected an error'));
})
.catch(err => {
assert.strictEqual('Image to trim must be at least 3x3 pixels', err.message);
done();
})
.catch(done);
});
describe('Invalid thresholds', function () {
[-1, 'fail', {}].forEach(function (threshold) {
it(JSON.stringify(threshold), function () {

View File

@@ -118,6 +118,13 @@ describe('Utilities', function () {
assert.strictEqual(true, sharp.format.raw[direction].stream);
});
});
it('vips format supports filesystem only', function () {
['input', 'output'].forEach(function (direction) {
assert.strictEqual(true, sharp.format.vips[direction].file);
assert.strictEqual(false, sharp.format.vips[direction].buffer);
assert.strictEqual(false, sharp.format.vips[direction].stream);
});
});
});
describe('Versions', function () {