Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f384e1c6c | ||
|
|
35e8c8b25e | ||
|
|
dc53f1baff | ||
|
|
70139600b5 | ||
|
|
1b4d1521e0 | ||
|
|
ed3377cb2d | ||
|
|
d72852b3aa | ||
|
|
4b6b6189bf | ||
|
|
b69a54fc75 | ||
|
|
81e388a4cc | ||
|
|
5bd5e5052a | ||
|
|
a2d3fa729f | ||
|
|
cb6811bc47 | ||
|
|
53c6e80869 | ||
|
|
e71dca586c | ||
|
|
b3cd48db5f | ||
|
|
476448b9d4 | ||
|
|
070534df5b | ||
|
|
9a1e8ed574 | ||
|
|
309918a878 | ||
|
|
cac83b94c1 | ||
|
|
9c06df08a1 | ||
|
|
52e4543d31 | ||
|
|
a688468378 | ||
|
|
e1760d64fb | ||
|
|
84d4e3cf8f | ||
|
|
f8a76372ad | ||
|
|
4237f5520f | ||
|
|
8c0c01c702 | ||
|
|
9c100830e0 | ||
|
|
ed5d753b89 | ||
|
|
d1ca756bd8 |
@@ -5,6 +5,7 @@ task:
|
||||
name: FreeBSD 13.0
|
||||
env:
|
||||
IGNORE_OSVERSION: yes
|
||||
skip_notifications: true
|
||||
prerequisites_script:
|
||||
- pkg update -f
|
||||
- pkg upgrade -y
|
||||
|
||||
8
.github/workflows/ci.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
nodejs_version: 14
|
||||
- os: ubuntu-20.04
|
||||
container: centos:7
|
||||
nodejs_version: 15
|
||||
nodejs_version: 16
|
||||
- os: ubuntu-20.04
|
||||
container: node:10-alpine3.11
|
||||
prebuild: true
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- os: ubuntu-20.04
|
||||
container: node:14-alpine3.13
|
||||
- os: ubuntu-20.04
|
||||
container: node:15-alpine3.11
|
||||
container: node:16-alpine3.11
|
||||
- os: macos-10.15
|
||||
nodejs_version: 10
|
||||
prebuild: true
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
- os: macos-10.15
|
||||
nodejs_version: 14
|
||||
- os: macos-10.15
|
||||
nodejs_version: 15
|
||||
nodejs_version: 16
|
||||
- os: windows-2019
|
||||
nodejs_version: 10
|
||||
prebuild: true
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
- os: windows-2019
|
||||
nodejs_version: 14
|
||||
- os: windows-2019
|
||||
nodejs_version: 15
|
||||
nodejs_version: 16
|
||||
steps:
|
||||
- name: Dependencies (Linux glibc)
|
||||
if: contains(matrix.container, 'centos')
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
install: sudo docker exec sharp sh -c "npm install --build-from-source --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
|
||||
- name: "Linux ARM64v8 (Debian 11, glibc 2.29) - Node.js 15"
|
||||
- name: "Linux ARM64v8 (Debian 11, glibc 2.29) - Node.js 16"
|
||||
arch: arm64
|
||||
os: linux
|
||||
dist: bionic
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
- sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp arm64v8/debian:bullseye
|
||||
- sudo docker exec sharp sh -c "apt-get update && apt-get install -y build-essential git python3 curl"
|
||||
- sudo docker exec sharp sh -c "curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -"
|
||||
- sudo docker exec sharp sh -c "echo 'deb https://deb.nodesource.com/node_15.x sid main' >/etc/apt/sources.list.d/nodesource.list"
|
||||
- sudo docker exec sharp sh -c "echo 'deb https://deb.nodesource.com/node_16.x sid main' >/etc/apt/sources.list.d/nodesource.list"
|
||||
- sudo docker exec sharp sh -c "apt-get update && apt-get install -y nodejs"
|
||||
install: sudo docker exec sharp sh -c "npm install --build-from-source --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
@@ -92,14 +92,14 @@ jobs:
|
||||
install: sudo docker exec sharp sh -c "npm install --build-from-source --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
|
||||
- name: "Linux ARM64v8 (Alpine 3.11, musl 1.1.24) - Node.js 15"
|
||||
- name: "Linux ARM64v8 (Alpine 3.11, musl 1.1.24) - Node.js 16"
|
||||
arch: arm64
|
||||
os: linux
|
||||
dist: focal
|
||||
language: shell
|
||||
before_install:
|
||||
- sudo chown 0.0 ${PWD}
|
||||
- sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:15-alpine3.11
|
||||
- sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:16-alpine3.11
|
||||
- sudo docker exec sharp sh -c "apk add build-base git python3 --update-cache"
|
||||
install: sudo docker exec sharp sh -c "npm install --build-from-source --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
|
||||
@@ -8,7 +8,7 @@ environment:
|
||||
prebuild: true
|
||||
- nodejs_version: "12"
|
||||
- nodejs_version: "14"
|
||||
- nodejs_version: "15"
|
||||
- nodejs_version: "16"
|
||||
install:
|
||||
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)
|
||||
- npm install --build-from-source
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.
|
||||
|
||||
See also [flatten][1].
|
||||
|
||||
### Examples
|
||||
|
||||
```javascript
|
||||
@@ -25,7 +27,7 @@ This is a no-op if the image already has an alpha channel.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `alpha` **[number][1]** alpha transparency level (0=fully-transparent, 1=fully-opaque) (optional, default `1`)
|
||||
* `alpha` **[number][2]** alpha transparency level (0=fully-transparent, 1=fully-opaque) (optional, default `1`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -43,13 +45,13 @@ const rgba = await sharp(rgb)
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
- Throws **[Error][2]** Invalid alpha transparency level
|
||||
* Throws **[Error][3]** Invalid alpha transparency level
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.21.2
|
||||
* **since**: 0.21.2
|
||||
|
||||
## extractChannel
|
||||
|
||||
@@ -57,7 +59,7 @@ Extract a single channel from a multi-channel image.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `channel` **([number][1] \| [string][3])** zero-indexed channel/band number to extract, or `red`, `green`, `blue` or `alpha`.
|
||||
* `channel` **([number][2] | [string][4])** zero-indexed channel/band number to extract, or `red`, `green`, `blue` or `alpha`.
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -71,7 +73,7 @@ sharp(input)
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][2]** Invalid channel
|
||||
* Throws **[Error][3]** Invalid channel
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -82,19 +84,20 @@ The meaning of the added channels depends on the output colourspace, set with `t
|
||||
By default the output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
|
||||
Channel ordering follows vips convention:
|
||||
|
||||
- sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha.
|
||||
- CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha.
|
||||
* sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha.
|
||||
* CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha.
|
||||
|
||||
Buffers may be any of the image formats supported by sharp.
|
||||
For raw pixel input, the `options` object should contain a `raw` attribute, which follows the format of the attribute of the same name in the `sharp()` constructor.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `images` **([Array][4]<([string][3] \| [Buffer][5])> | [string][3] \| [Buffer][5])** one or more images (file paths, Buffers).
|
||||
- `options` **[Object][6]** image options, see `sharp()` constructor.
|
||||
* `images` **([Array][5]<([string][4] | [Buffer][6])> | [string][4] | [Buffer][6])** one or more images (file paths, Buffers).
|
||||
* `options` **[Object][7]** image options, see `sharp()` constructor.
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][2]** Invalid parameters
|
||||
* Throws **[Error][3]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -104,7 +107,7 @@ Perform a bitwise boolean operation on all input image channels (bands) to produ
|
||||
|
||||
### Parameters
|
||||
|
||||
- `boolOp` **[string][3]** one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
|
||||
* `boolOp` **[string][4]** one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -118,18 +121,20 @@ sharp('3-channel-rgb-input.png')
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][2]** Invalid parameters
|
||||
* Throws **[Error][3]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
||||
[1]: /api-operation#flatten
|
||||
|
||||
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
|
||||
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
||||
|
||||
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
|
||||
|
||||
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
||||
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
|
||||
[5]: https://nodejs.org/api/buffer.html
|
||||
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
||||
|
||||
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||
[6]: https://nodejs.org/api/buffer.html
|
||||
|
||||
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||
|
||||
@@ -7,10 +7,11 @@ An alpha channel may be present and will be unchanged by the operation.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `rgb` **([string][1] \| [Object][2])** parsed by the [color][3] module to extract chroma values.
|
||||
* `rgb` **([string][1] | [Object][2])** parsed by the [color][3] module to extract chroma values.
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][4]** Invalid parameter
|
||||
* Throws **[Error][4]** Invalid parameter
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -25,7 +26,7 @@ An alpha channel may be present, and will be unchanged by the operation.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `greyscale` **[Boolean][5]** (optional, default `true`)
|
||||
* `greyscale` **[Boolean][5]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -35,7 +36,7 @@ Alternative spelling of `greyscale`.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `grayscale` **[Boolean][5]** (optional, default `true`)
|
||||
* `grayscale` **[Boolean][5]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -46,7 +47,7 @@ By default output image will be web-friendly sRGB, with additional channels inte
|
||||
|
||||
### Parameters
|
||||
|
||||
- `colourspace` **[string][1]?** output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...][6]
|
||||
* `colourspace` **[string][1]?** output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...][6]
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -57,7 +58,7 @@ await sharp(input)
|
||||
.toFile('16-bpp.png')
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid parameters
|
||||
* Throws **[Error][4]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -67,10 +68,11 @@ Alternative spelling of `toColourspace`.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `colorspace` **[string][1]?** output colorspace.
|
||||
* `colorspace` **[string][1]?** output colorspace.
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][4]** Invalid parameters
|
||||
* Throws **[Error][4]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
|
||||
@@ -19,24 +19,30 @@ and [https://www.cairographics.org/operators/][2]
|
||||
|
||||
### Parameters
|
||||
|
||||
- `images` **[Array][3]<[Object][4]>** Ordered list of images to composite
|
||||
- `images[].input` **([Buffer][5] \| [String][6])?** Buffer containing image data, String containing the path to an image file, or Create object (see below)
|
||||
- `images[].input.create` **[Object][4]?** describes a blank overlay to be created.
|
||||
- `images[].input.create.width` **[Number][7]?**
|
||||
- `images[].input.create.height` **[Number][7]?**
|
||||
- `images[].input.create.channels` **[Number][7]?** 3-4
|
||||
- `images[].input.create.background` **([String][6] \| [Object][4])?** parsed by the [color][8] module to extract values for red, green, blue and alpha.
|
||||
- `images[].blend` **[String][6]** how to blend this image with the image below. (optional, default `'over'`)
|
||||
- `images[].gravity` **[String][6]** gravity at which to place the overlay. (optional, default `'centre'`)
|
||||
- `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]?**
|
||||
- `images[].raw.height` **[Number][7]?**
|
||||
- `images[].raw.channels` **[Number][7]?**
|
||||
* `images` **[Array][3]<[Object][4]>** Ordered list of images to composite
|
||||
|
||||
* `images[].input` **([Buffer][5] | [String][6])?** Buffer containing image data, String containing the path to an image file, or Create object (see below)
|
||||
|
||||
* `images[].input.create` **[Object][4]?** describes a blank overlay to be created.
|
||||
|
||||
* `images[].input.create.width` **[Number][7]?**
|
||||
* `images[].input.create.height` **[Number][7]?**
|
||||
* `images[].input.create.channels` **[Number][7]?** 3-4
|
||||
* `images[].input.create.background` **([String][6] | [Object][4])?** parsed by the [color][8] module to extract values for red, green, blue and alpha.
|
||||
* `images[].blend` **[String][6]** how to blend this image with the image below. (optional, default `'over'`)
|
||||
* `images[].gravity` **[String][6]** gravity at which to place the overlay. (optional, default `'centre'`)
|
||||
* `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]?**
|
||||
* `images[].raw.height` **[Number][7]?**
|
||||
* `images[].raw.channels` **[Number][7]?**
|
||||
* `images[].failOnError` **[boolean][9]** @see [constructor parameters][10] (optional, default `true`)
|
||||
* `images[].limitInputPixels` **([number][7] | [boolean][9])** @see [constructor parameters][10] (optional, default `268402689`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -57,13 +63,13 @@ sharp('input.png')
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][10]** Invalid parameters
|
||||
* Throws **[Error][11]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.22.0
|
||||
* **since**: 0.22.0
|
||||
|
||||
[1]: https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
|
||||
|
||||
@@ -83,4 +89,6 @@ Returns **Sharp**
|
||||
|
||||
[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
||||
|
||||
[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
|
||||
[10]: /api-constructor#parameters
|
||||
|
||||
[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
|
||||
|
||||
@@ -13,37 +13,43 @@ Implements the [stream.Duplex][1] class.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `input` **([Buffer][2] \| [Uint8Array][3] \| [Uint8ClampedArray][4] \| [string][5])?** if present, can be
|
||||
a Buffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data, or
|
||||
a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
||||
JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
||||
- `options` **[Object][6]?** if present, is an Object with optional attributes.
|
||||
- `options.failOnError` **[boolean][7]** by default halt processing and raise an error when loading invalid images.
|
||||
Set this flag to `false` if you'd rather apply a "best effort" to decode images, even if the data is corrupt or invalid. (optional, default `true`)
|
||||
- `options.limitInputPixels` **([number][8] \| [boolean][7])** Do not process input images where the number of pixels
|
||||
(width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
||||
An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). (optional, default `268402689`)
|
||||
- `options.sequentialRead` **[boolean][7]** Set this to `true` to use sequential rather than random access where possible.
|
||||
This can reduce memory usage and might improve performance on some systems. (optional, default `false`)
|
||||
- `options.density` **[number][8]** number representing the DPI for vector images in the range 1 to 100000. (optional, default `72`)
|
||||
- `options.pages` **[number][8]** number of pages to extract for multi-page input (GIF, WebP, AVIF, TIFF, PDF), use -1 for all pages. (optional, default `1`)
|
||||
- `options.page` **[number][8]** page number to start extracting from for multi-page input (GIF, WebP, AVIF, TIFF, PDF), zero based. (optional, default `0`)
|
||||
- `options.subifd` **[number][8]** subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. (optional, default `-1`)
|
||||
- `options.level` **[number][8]** level to extract from a multi-level input (OpenSlide), zero based. (optional, default `0`)
|
||||
- `options.animated` **[boolean][7]** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default `false`)
|
||||
- `options.raw` **[Object][6]?** describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||
- `options.raw.width` **[number][8]?** integral number of pixels wide.
|
||||
- `options.raw.height` **[number][8]?** integral number of pixels high.
|
||||
- `options.raw.channels` **[number][8]?** integral number of channels, between 1 and 4.
|
||||
- `options.create` **[Object][6]?** describes a new image to be created.
|
||||
- `options.create.width` **[number][8]?** integral number of pixels wide.
|
||||
- `options.create.height` **[number][8]?** integral number of pixels high.
|
||||
- `options.create.channels` **[number][8]?** integral number of channels, either 3 (RGB) or 4 (RGBA).
|
||||
- `options.create.background` **([string][5] \| [Object][6])?** parsed by the [color][9] module to extract values for red, green, blue and alpha.
|
||||
- `options.create.noise` **[Object][6]?** describes a noise to be created.
|
||||
- `options.create.noise.type` **[string][5]?** type of generated noise, currently only `gaussian` is supported.
|
||||
- `options.create.noise.mean` **[number][8]?** mean of pixels in generated noise.
|
||||
- `options.create.noise.sigma` **[number][8]?** standard deviation of pixels in generated noise.
|
||||
* `input` **([Buffer][2] | [Uint8Array][3] | [Uint8ClampedArray][4] | [string][5])?** if present, can be
|
||||
a Buffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data, or
|
||||
a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
||||
JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
||||
* `options` **[Object][6]?** if present, is an Object with optional attributes.
|
||||
|
||||
* `options.failOnError` **[boolean][7]** by default halt processing and raise an error when loading invalid images.
|
||||
Set this flag to `false` if you'd rather apply a "best effort" to decode images, even if the data is corrupt or invalid. (optional, default `true`)
|
||||
* `options.limitInputPixels` **([number][8] | [boolean][7])** Do not process input images where the number of pixels
|
||||
(width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
||||
An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). (optional, default `268402689`)
|
||||
* `options.sequentialRead` **[boolean][7]** Set this to `true` to use sequential rather than random access where possible.
|
||||
This can reduce memory usage and might improve performance on some systems. (optional, default `false`)
|
||||
* `options.density` **[number][8]** number representing the DPI for vector images in the range 1 to 100000. (optional, default `72`)
|
||||
* `options.pages` **[number][8]** number of pages to extract for multi-page input (GIF, WebP, AVIF, TIFF, PDF), use -1 for all pages. (optional, default `1`)
|
||||
* `options.page` **[number][8]** page number to start extracting from for multi-page input (GIF, WebP, AVIF, TIFF, PDF), zero based. (optional, default `0`)
|
||||
* `options.subifd` **[number][8]** subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. (optional, default `-1`)
|
||||
* `options.level` **[number][8]** level to extract from a multi-level input (OpenSlide), zero based. (optional, default `0`)
|
||||
* `options.animated` **[boolean][7]** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default `false`)
|
||||
* `options.raw` **[Object][6]?** describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||
|
||||
* `options.raw.width` **[number][8]?** integral number of pixels wide.
|
||||
* `options.raw.height` **[number][8]?** integral number of pixels high.
|
||||
* `options.raw.channels` **[number][8]?** integral number of channels, between 1 and 4.
|
||||
* `options.raw.premultiplied` **[boolean][7]?** specifies that the raw input has already been premultiplied, set to `true`
|
||||
to avoid sharp premultiplying the image. (optional, default `false`)
|
||||
* `options.create` **[Object][6]?** describes a new image to be created.
|
||||
|
||||
* `options.create.width` **[number][8]?** integral number of pixels wide.
|
||||
* `options.create.height` **[number][8]?** integral number of pixels high.
|
||||
* `options.create.channels` **[number][8]?** integral number of channels, either 3 (RGB) or 4 (RGBA).
|
||||
* `options.create.background` **([string][5] | [Object][6])?** parsed by the [color][9] module to extract values for red, green, blue and alpha.
|
||||
* `options.create.noise` **[Object][6]?** describes a noise to be created.
|
||||
|
||||
* `options.create.noise.type` **[string][5]?** type of generated noise, currently only `gaussian` is supported.
|
||||
* `options.create.noise.mean` **[number][8]?** mean of pixels in generated noise.
|
||||
* `options.create.noise.sigma` **[number][8]?** standard deviation of pixels in generated noise.
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -120,7 +126,7 @@ await sharp({
|
||||
}).toFile('noise.png');
|
||||
```
|
||||
|
||||
- Throws **[Error][10]** Invalid parameters
|
||||
* Throws **[Error][10]** Invalid parameters
|
||||
|
||||
Returns **[Sharp][11]**
|
||||
|
||||
|
||||
@@ -5,35 +5,35 @@
|
||||
Fast access to (uncached) image metadata without decoding any compressed image data.
|
||||
A `Promise` is returned when `callback` is not provided.
|
||||
|
||||
- `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
|
||||
- `size`: Total size of image in bytes, for Stream and Buffer input only
|
||||
- `width`: Number of pixels wide (EXIF orientation is not taken into consideration)
|
||||
- `height`: Number of pixels high (EXIF orientation is not taken into consideration)
|
||||
- `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...][1]
|
||||
- `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
||||
- `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...][2]
|
||||
- `density`: Number of pixels per inch (DPI), if present
|
||||
- `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
||||
- `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
||||
- `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
||||
- `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
||||
- `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
||||
- `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
||||
- `pagePrimary`: Number of the primary page in a HEIF image
|
||||
- `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
||||
- `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
||||
- `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
||||
- `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
|
||||
- `orientation`: Number value of the EXIF Orientation header, if present
|
||||
- `exif`: Buffer containing raw EXIF data, if present
|
||||
- `icc`: Buffer containing raw [ICC][3] profile data, if present
|
||||
- `iptc`: Buffer containing raw IPTC data, if present
|
||||
- `xmp`: Buffer containing raw XMP data, if present
|
||||
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
||||
* `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
|
||||
* `size`: Total size of image in bytes, for Stream and Buffer input only
|
||||
* `width`: Number of pixels wide (EXIF orientation is not taken into consideration)
|
||||
* `height`: Number of pixels high (EXIF orientation is not taken into consideration)
|
||||
* `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...][1]
|
||||
* `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
||||
* `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...][2]
|
||||
* `density`: Number of pixels per inch (DPI), if present
|
||||
* `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
||||
* `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
||||
* `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
||||
* `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
||||
* `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
||||
* `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
||||
* `pagePrimary`: Number of the primary page in a HEIF image
|
||||
* `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
||||
* `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
||||
* `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
||||
* `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
|
||||
* `orientation`: Number value of the EXIF Orientation header, if present
|
||||
* `exif`: Buffer containing raw EXIF data, if present
|
||||
* `icc`: Buffer containing raw [ICC][3] profile data, if present
|
||||
* `iptc`: Buffer containing raw IPTC data, if present
|
||||
* `xmp`: Buffer containing raw XMP data, if present
|
||||
* `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
||||
|
||||
### Parameters
|
||||
|
||||
- `callback` **[Function][4]?** called with the arguments `(err, metadata)`
|
||||
* `callback` **[Function][4]?** called with the arguments `(err, metadata)`
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -52,32 +52,32 @@ image
|
||||
});
|
||||
```
|
||||
|
||||
Returns **([Promise][5]<[Object][6]> | Sharp)**
|
||||
Returns **([Promise][5]<[Object][6]> | Sharp)**
|
||||
|
||||
## stats
|
||||
|
||||
Access to pixel-derived image statistics for every channel in the image.
|
||||
A `Promise` is returned when `callback` is not provided.
|
||||
|
||||
- `channels`: Array of channel statistics for each channel in the image. Each channel statistic contains
|
||||
- `min` (minimum value in the channel)
|
||||
- `max` (maximum value in the channel)
|
||||
- `sum` (sum of all values in a channel)
|
||||
- `squaresSum` (sum of squared values in a channel)
|
||||
- `mean` (mean of the values in a channel)
|
||||
- `stdev` (standard deviation for the values in a channel)
|
||||
- `minX` (x-coordinate of one of the pixel where the minimum lies)
|
||||
- `minY` (y-coordinate of one of the pixel where the minimum lies)
|
||||
- `maxX` (x-coordinate of one of the pixel where the maximum lies)
|
||||
- `maxY` (y-coordinate of one of the pixel where the maximum lies)
|
||||
- `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
|
||||
- `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any (experimental)
|
||||
- `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any (experimental)
|
||||
- `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram (experimental)
|
||||
* `channels`: Array of channel statistics for each channel in the image. Each channel statistic contains
|
||||
* `min` (minimum value in the channel)
|
||||
* `max` (maximum value in the channel)
|
||||
* `sum` (sum of all values in a channel)
|
||||
* `squaresSum` (sum of squared values in a channel)
|
||||
* `mean` (mean of the values in a channel)
|
||||
* `stdev` (standard deviation for the values in a channel)
|
||||
* `minX` (x-coordinate of one of the pixel where the minimum lies)
|
||||
* `minY` (y-coordinate of one of the pixel where the minimum lies)
|
||||
* `maxX` (x-coordinate of one of the pixel where the maximum lies)
|
||||
* `maxY` (y-coordinate of one of the pixel where the maximum lies)
|
||||
* `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
|
||||
* `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any (experimental)
|
||||
* `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any (experimental)
|
||||
* `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram (experimental)
|
||||
|
||||
### Parameters
|
||||
|
||||
- `callback` **[Function][4]?** called with the arguments `(err, stats)`
|
||||
* `callback` **[Function][4]?** called with the arguments `(err, stats)`
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -95,7 +95,7 @@ const { entropy, sharpness, dominant } = await sharp(input).stats();
|
||||
const { r, g, b } = dominant;
|
||||
```
|
||||
|
||||
Returns **[Promise][5]<[Object][6]>**
|
||||
Returns **[Promise][5]<[Object][6]>**
|
||||
|
||||
[1]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation
|
||||
|
||||
|
||||
@@ -21,9 +21,10 @@ for example `rotate(x).extract(y)` will produce a different result to `extract(y
|
||||
|
||||
### Parameters
|
||||
|
||||
- `angle` **[number][1]** angle of rotation. (optional, default `auto`)
|
||||
- `options` **[Object][2]?** if present, is an Object with optional attributes.
|
||||
- `options.background` **([string][3] \| [Object][2])** parsed by the [color][4] module to extract values for red, green, blue and alpha. (optional, default `"#000000"`)
|
||||
* `angle` **[number][1]** angle of rotation. (optional, default `auto`)
|
||||
* `options` **[Object][2]?** if present, is an Object with optional attributes.
|
||||
|
||||
* `options.background` **([string][3] | [Object][2])** parsed by the [color][4] module to extract values for red, green, blue and alpha. (optional, default `"#000000"`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -39,7 +40,7 @@ const pipeline = sharp()
|
||||
readableStream.pipe(pipeline);
|
||||
```
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -50,7 +51,7 @@ The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `flip` **[Boolean][6]** (optional, default `true`)
|
||||
* `flip` **[Boolean][6]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -61,7 +62,7 @@ The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `flop` **[Boolean][6]** (optional, default `true`)
|
||||
* `flop` **[Boolean][6]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -75,25 +76,26 @@ A particular interpolator may also be specified. Set the `interpolator` option t
|
||||
|
||||
In the case of a 2x2 matrix, the transform is:
|
||||
|
||||
- X = `matrix[0, 0]` \* (x + `idx`) + `matrix[0, 1]` \* (y + `idy`) + `odx`
|
||||
- Y = `matrix[1, 0]` \* (x + `idx`) + `matrix[1, 1]` \* (y + `idy`) + `ody`
|
||||
* X = `matrix[0, 0]` \* (x + `idx`) + `matrix[0, 1]` \* (y + `idy`) + `odx`
|
||||
* Y = `matrix[1, 0]` \* (x + `idx`) + `matrix[1, 1]` \* (y + `idy`) + `ody`
|
||||
|
||||
where:
|
||||
|
||||
- x and y are the coordinates in input image.
|
||||
- X and Y are the coordinates in output image.
|
||||
- (0,0) is the upper left corner.
|
||||
* x and y are the coordinates in input image.
|
||||
* X and Y are the coordinates in output image.
|
||||
* (0,0) is the upper left corner.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `matrix` **([Array][7]<[Array][7]<[number][1]>> | [Array][7]<[number][1]>)** affine transformation matrix
|
||||
- `options` **[Object][2]?** if present, is an Object with optional attributes.
|
||||
- `options.background` **([String][3] \| [Object][2])** parsed by the [color][4] module to extract values for red, green, blue and alpha. (optional, default `"#000000"`)
|
||||
- `options.idx` **[Number][1]** input horizontal offset (optional, default `0`)
|
||||
- `options.idy` **[Number][1]** input vertical offset (optional, default `0`)
|
||||
- `options.odx` **[Number][1]** output horizontal offset (optional, default `0`)
|
||||
- `options.ody` **[Number][1]** output vertical offset (optional, default `0`)
|
||||
- `options.interpolator` **[String][3]** interpolator (optional, default `sharp.interpolators.bicubic`)
|
||||
* `matrix` **([Array][7]<[Array][7]<[number][1]>> | [Array][7]<[number][1]>)** affine transformation matrix
|
||||
* `options` **[Object][2]?** if present, is an Object with optional attributes.
|
||||
|
||||
* `options.background` **([String][3] | [Object][2])** parsed by the [color][4] module to extract values for red, green, blue and alpha. (optional, default `"#000000"`)
|
||||
* `options.idx` **[Number][1]** input horizontal offset (optional, default `0`)
|
||||
* `options.idy` **[Number][1]** input vertical offset (optional, default `0`)
|
||||
* `options.odx` **[Number][1]** output horizontal offset (optional, default `0`)
|
||||
* `options.ody` **[Number][1]** output vertical offset (optional, default `0`)
|
||||
* `options.interpolator` **[String][3]** interpolator (optional, default `sharp.interpolators.bicubic`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -112,13 +114,13 @@ inputStream
|
||||
.pipe(pipeline);
|
||||
```
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.27.0
|
||||
* **since**: 0.27.0
|
||||
|
||||
## sharpen
|
||||
|
||||
@@ -129,12 +131,13 @@ Separate control over the level of sharpening in "flat" and "jagged" areas is av
|
||||
|
||||
### Parameters
|
||||
|
||||
- `sigma` **[number][1]?** the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
||||
- `flat` **[number][1]** the level of sharpening to apply to "flat" areas. (optional, default `1.0`)
|
||||
- `jagged` **[number][1]** the level of sharpening to apply to "jagged" areas. (optional, default `2.0`)
|
||||
* `sigma` **[number][1]?** the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
||||
* `flat` **[number][1]** the level of sharpening to apply to "flat" areas. (optional, default `1.0`)
|
||||
* `jagged` **[number][1]** the level of sharpening to apply to "jagged" areas. (optional, default `2.0`)
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -145,10 +148,11 @@ When used without parameters the default window is 3x3.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `size` **[number][1]** square mask size: size x size (optional, default `3`)
|
||||
* `size` **[number][1]** square mask size: size x size (optional, default `3`)
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -160,10 +164,11 @@ When a `sigma` is provided, performs a slower, more accurate Gaussian blur.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `sigma` **[number][1]?** a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
||||
* `sigma` **[number][1]?** a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -171,16 +176,19 @@ Returns **Sharp**
|
||||
|
||||
Merge alpha transparency channel, if any, with a background, then remove the alpha channel.
|
||||
|
||||
See also [removeAlpha][8].
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][2]?**
|
||||
- `options.background` **([string][3] \| [Object][2])** background colour, parsed by the [color][4] module, defaults to black. (optional, default `{r:0,g:0,b:0}`)
|
||||
* `options` **[Object][2]?**
|
||||
|
||||
* `options.background` **([string][3] | [Object][2])** background colour, parsed by the [color][4] module, defaults to black. (optional, default `{r:0,g:0,b:0}`)
|
||||
|
||||
### Examples
|
||||
|
||||
```javascript
|
||||
await sharp(rgbaInput)
|
||||
.flatten('#F0A703')
|
||||
.flatten({ background: '#F0A703' })
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
@@ -198,11 +206,12 @@ Supply a second argument to use a different output gamma value, otherwise the fi
|
||||
|
||||
### Parameters
|
||||
|
||||
- `gamma` **[number][1]** value between 1.0 and 3.0. (optional, default `2.2`)
|
||||
- `gammaOut` **[number][1]?** value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
|
||||
* `gamma` **[number][1]** value between 1.0 and 3.0. (optional, default `2.2`)
|
||||
* `gammaOut` **[number][1]?** value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -212,7 +221,7 @@ Produce the "negative" of the image.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `negate` **[Boolean][6]** (optional, default `true`)
|
||||
* `negate` **[Boolean][6]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -222,7 +231,7 @@ Enhance output image contrast by stretching its luminance to cover the full dyna
|
||||
|
||||
### Parameters
|
||||
|
||||
- `normalise` **[Boolean][6]** (optional, default `true`)
|
||||
* `normalise` **[Boolean][6]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -232,22 +241,50 @@ Alternative spelling of normalise.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `normalize` **[Boolean][6]** (optional, default `true`)
|
||||
* `normalize` **[Boolean][6]** (optional, default `true`)
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
## clahe
|
||||
|
||||
Perform contrast limiting adaptive histogram equalization
|
||||
[CLAHE][9].
|
||||
|
||||
This will, in general, enhance the clarity of the image by bringing out darker details.
|
||||
|
||||
### Parameters
|
||||
|
||||
* `options` **[Object][2]**
|
||||
|
||||
* `options.width` **[number][1]** integer width of the region in pixels.
|
||||
* `options.height` **[number][1]** integer height of the region in pixels.
|
||||
* `options.maxSlope` **[number][1]** maximum value for the slope of the
|
||||
cumulative histogram. A value of 0 disables contrast limiting. Valid values
|
||||
are integers in the range 0-100 (inclusive) (optional, default `3`)
|
||||
|
||||
<!---->
|
||||
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
* **since**: 0.28.3
|
||||
|
||||
## convolve
|
||||
|
||||
Convolve the image with the specified kernel.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `kernel` **[Object][2]**
|
||||
- `kernel.width` **[number][1]** width of the kernel in pixels.
|
||||
- `kernel.height` **[number][1]** width of the kernel in pixels.
|
||||
- `kernel.kernel` **[Array][7]<[number][1]>** Array of length `width*height` containing the kernel values.
|
||||
- `kernel.scale` **[number][1]** the scale of the kernel in pixels. (optional, default `sum`)
|
||||
- `kernel.offset` **[number][1]** the offset of the kernel in pixels. (optional, default `0`)
|
||||
* `kernel` **[Object][2]**
|
||||
|
||||
* `kernel.width` **[number][1]** width of the kernel in pixels.
|
||||
* `kernel.height` **[number][1]** height of the kernel in pixels.
|
||||
* `kernel.kernel` **[Array][7]<[number][1]>** Array of length `width*height` containing the kernel values.
|
||||
* `kernel.scale` **[number][1]** the scale of the kernel in pixels. (optional, default `sum`)
|
||||
* `kernel.offset` **[number][1]** the offset of the kernel in pixels. (optional, default `0`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -265,7 +302,7 @@ sharp(input)
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -275,13 +312,15 @@ Any pixel value greater than or equal to the threshold value will be set to 255,
|
||||
|
||||
### Parameters
|
||||
|
||||
- `threshold` **[number][1]** a value in the range 0-255 representing the level at which the threshold will be applied. (optional, default `128`)
|
||||
- `options` **[Object][2]?**
|
||||
- `options.greyscale` **[Boolean][6]** convert to single channel greyscale. (optional, default `true`)
|
||||
- `options.grayscale` **[Boolean][6]** alternative spelling for greyscale. (optional, default `true`)
|
||||
* `threshold` **[number][1]** a value in the range 0-255 representing the level at which the threshold will be applied. (optional, default `128`)
|
||||
* `options` **[Object][2]?**
|
||||
|
||||
* `options.greyscale` **[Boolean][6]** convert to single channel greyscale. (optional, default `true`)
|
||||
* `options.grayscale` **[Boolean][6]** alternative spelling for greyscale. (optional, default `true`)
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
<!---->
|
||||
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -294,16 +333,19 @@ the selected bitwise boolean `operation` between the corresponding pixels of the
|
||||
|
||||
### Parameters
|
||||
|
||||
- `operand` **([Buffer][8] \| [string][3])** Buffer containing image data or string containing the path to an image file.
|
||||
- `operator` **[string][3]** one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
|
||||
- `options` **[Object][2]?**
|
||||
- `options.raw` **[Object][2]?** describes operand when using raw pixel data.
|
||||
- `options.raw.width` **[number][1]?**
|
||||
- `options.raw.height` **[number][1]?**
|
||||
- `options.raw.channels` **[number][1]?**
|
||||
* `operand` **([Buffer][10] | [string][3])** Buffer containing image data or string containing the path to an image file.
|
||||
* `operator` **[string][3]** one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
|
||||
* `options` **[Object][2]?**
|
||||
|
||||
* `options.raw` **[Object][2]?** describes operand when using raw pixel data.
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* `options.raw.width` **[number][1]?**
|
||||
* `options.raw.height` **[number][1]?**
|
||||
* `options.raw.channels` **[number][1]?**
|
||||
|
||||
<!---->
|
||||
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -313,11 +355,12 @@ Apply the linear formula a \* input + b to the image (levels adjustment)
|
||||
|
||||
### Parameters
|
||||
|
||||
- `a` **[number][1]** multiplier (optional, default `1.0`)
|
||||
- `b` **[number][1]** offset (optional, default `0.0`)
|
||||
* `a` **[number][1]** multiplier (optional, default `1.0`)
|
||||
* `b` **[number][1]** offset (optional, default `0.0`)
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -327,7 +370,7 @@ Recomb the image with the specified matrix.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `inputMatrix` **[Array][7]<[Array][7]<[number][1]>>** 3x3 Recombination matrix
|
||||
* `inputMatrix` **[Array][7]<[Array][7]<[number][1]>>** 3x3 Recombination matrix
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -345,13 +388,13 @@ sharp(input)
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][5]** Invalid parameters
|
||||
* Throws **[Error][5]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.21.1
|
||||
* **since**: 0.21.1
|
||||
|
||||
## modulate
|
||||
|
||||
@@ -359,10 +402,11 @@ Transforms the image using brightness, saturation and hue rotation.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][2]?**
|
||||
- `options.brightness` **[number][1]?** Brightness multiplier
|
||||
- `options.saturation` **[number][1]?** Saturation multiplier
|
||||
- `options.hue` **[number][1]?** Degrees for hue rotation
|
||||
* `options` **[Object][2]?**
|
||||
|
||||
* `options.brightness` **[number][1]?** Brightness multiplier
|
||||
* `options.saturation` **[number][1]?** Saturation multiplier
|
||||
* `options.hue` **[number][1]?** Degrees for hue rotation
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -390,7 +434,7 @@ Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.22.1
|
||||
* **since**: 0.22.1
|
||||
|
||||
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
||||
|
||||
@@ -406,4 +450,8 @@ Returns **Sharp**
|
||||
|
||||
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
||||
|
||||
[8]: https://nodejs.org/api/buffer.html
|
||||
[8]: /api-channel#removealpha
|
||||
|
||||
[9]: https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE
|
||||
|
||||
[10]: https://nodejs.org/api/buffer.html
|
||||
|
||||
@@ -15,8 +15,8 @@ A `Promise` is returned when `callback` is not provided.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `fileOut` **[string][2]** the path to write the image data to.
|
||||
- `callback` **[Function][3]?** 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`.
|
||||
@@ -35,9 +35,9 @@ sharp(input)
|
||||
.catch(err => { ... });
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid parameters
|
||||
* Throws **[Error][4]** Invalid parameters
|
||||
|
||||
Returns **[Promise][5]<[Object][6]>** when no callback is provided
|
||||
Returns **[Promise][5]<[Object][6]>** when no callback is provided
|
||||
|
||||
## toBuffer
|
||||
|
||||
@@ -51,19 +51,21 @@ See [withMetadata][1] for control over this.
|
||||
|
||||
`callback`, if present, gets three arguments `(err, data, info)` where:
|
||||
|
||||
- `err` is an error, if any.
|
||||
- `data` is the output image data.
|
||||
- `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`.
|
||||
* `err` is an error, if any.
|
||||
* `data` is the output image data.
|
||||
* `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`.
|
||||
|
||||
A `Promise` is returned when `callback` is not provided.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `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]?**
|
||||
* `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
|
||||
|
||||
@@ -103,7 +105,7 @@ await sharp(pixelArray, { raw: { width, height, channels } })
|
||||
.toFile('my-changed-image.jpg');
|
||||
```
|
||||
|
||||
Returns **[Promise][5]<[Buffer][8]>** when no callback is provided
|
||||
Returns **[Promise][5]<[Buffer][8]>** when no callback is provided
|
||||
|
||||
## withMetadata
|
||||
|
||||
@@ -116,10 +118,12 @@ sRGB colour space and strip all metadata, including the removal of any ICC profi
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][6]?**
|
||||
- `options.orientation` **[number][9]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
|
||||
- `options.icc` **[string][2]?** filesystem path to output ICC profile, defaults to sRGB.
|
||||
- `options.exif` **[Object][6]<[Object][6]>** Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. (optional, default `{}`)
|
||||
* `options` **[Object][6]?**
|
||||
|
||||
* `options.orientation` **[number][9]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
|
||||
* `options.icc` **[string][2]?** filesystem path to output ICC profile, defaults to sRGB.
|
||||
* `options.exif` **[Object][6]<[Object][6]>** Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. (optional, default `{}`)
|
||||
* `options.density` **[number][9]?** Number of pixels per inch (DPI).
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -132,7 +136,7 @@ sharp('input.jpg')
|
||||
|
||||
```javascript
|
||||
// Set "IFD0-Copyright" in output EXIF metadata
|
||||
await sharp(input)
|
||||
const data = await sharp(input)
|
||||
.withMetadata({
|
||||
exif: {
|
||||
IFD0: {
|
||||
@@ -141,9 +145,15 @@ await sharp(input)
|
||||
}
|
||||
})
|
||||
.toBuffer();
|
||||
|
||||
* @example
|
||||
// Set output metadata to 96 DPI
|
||||
const data = await sharp(input)
|
||||
.withMetadata({ density: 96 })
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid parameters
|
||||
* Throws **[Error][4]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -153,8 +163,8 @@ Force output to a given format.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `format` **([string][2] \| [Object][6])** as a string or an Object with an 'id' attribute
|
||||
- `options` **[Object][6]** output options
|
||||
* `format` **([string][2] | [Object][6])** as a string or an Object with an 'id' attribute
|
||||
* `options` **[Object][6]** output options
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -165,7 +175,7 @@ const data = await sharp(input)
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** unsupported format or options
|
||||
* Throws **[Error][4]** unsupported format or options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -175,20 +185,21 @@ Use these JPEG options for output image.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `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 otherwise defaults to '4:2:0' chroma subsampling (optional, default `'4:2:0'`)
|
||||
- `options.optimiseCoding` **[boolean][7]** optimise Huffman coding tables (optional, default `true`)
|
||||
- `options.optimizeCoding` **[boolean][7]** alternative spelling of optimiseCoding (optional, default `true`)
|
||||
- `options.mozjpeg` **[boolean][7]** use mozjpeg defaults, equivalent to `{ trellisQuantisation: true, overshootDeringing: true, optimiseScans: true, quantisationTable: 3 }` (optional, default `false`)
|
||||
- `options.trellisQuantisation` **[boolean][7]** apply trellis quantisation (optional, default `false`)
|
||||
- `options.overshootDeringing` **[boolean][7]** apply overshoot deringing (optional, default `false`)
|
||||
- `options.optimiseScans` **[boolean][7]** optimise progressive scans, forces progressive (optional, default `false`)
|
||||
- `options.optimizeScans` **[boolean][7]** alternative spelling of optimiseScans (optional, default `false`)
|
||||
- `options.quantisationTable` **[number][9]** quantization table to use, integer 0-8 (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`)
|
||||
* `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 otherwise defaults to '4:2:0' chroma subsampling (optional, default `'4:2:0'`)
|
||||
* `options.optimiseCoding` **[boolean][7]** optimise Huffman coding tables (optional, default `true`)
|
||||
* `options.optimizeCoding` **[boolean][7]** alternative spelling of optimiseCoding (optional, default `true`)
|
||||
* `options.mozjpeg` **[boolean][7]** use mozjpeg defaults, equivalent to `{ trellisQuantisation: true, overshootDeringing: true, optimiseScans: true, quantisationTable: 3 }` (optional, default `false`)
|
||||
* `options.trellisQuantisation` **[boolean][7]** apply trellis quantisation (optional, default `false`)
|
||||
* `options.overshootDeringing` **[boolean][7]** apply overshoot deringing (optional, default `false`)
|
||||
* `options.optimiseScans` **[boolean][7]** optimise progressive scans, forces progressive (optional, default `false`)
|
||||
* `options.optimizeScans` **[boolean][7]** alternative spelling of optimiseScans (optional, default `false`)
|
||||
* `options.quantisationTable` **[number][9]** quantization table to use, integer 0-8 (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
|
||||
|
||||
@@ -209,7 +220,7 @@ const data = await sharp(input)
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -223,16 +234,17 @@ Set `palette` to `true` for slower, indexed PNG output.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][6]?**
|
||||
- `options.progressive` **[boolean][7]** use progressive (interlace) scan (optional, default `false`)
|
||||
- `options.compressionLevel` **[number][9]** zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest) (optional, default `6`)
|
||||
- `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 (optional, default `false`)
|
||||
- `options.quality` **[number][9]** use the lowest number of colours needed to achieve given quality, sets `palette` to `true` (optional, default `100`)
|
||||
- `options.colours` **[number][9]** maximum number of palette entries, sets `palette` to `true` (optional, default `256`)
|
||||
- `options.colors` **[number][9]** alternative spelling of `options.colours`, sets `palette` to `true` (optional, default `256`)
|
||||
- `options.dither` **[number][9]** level of Floyd-Steinberg error diffusion, sets `palette` to `true` (optional, default `1.0`)
|
||||
- `options.force` **[boolean][7]** 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 (fastest, largest) to 9 (slowest, smallest) (optional, default `6`)
|
||||
* `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 (optional, default `false`)
|
||||
* `options.quality` **[number][9]** use the lowest number of colours needed to achieve given quality, sets `palette` to `true` (optional, default `100`)
|
||||
* `options.colours` **[number][9]** maximum number of palette entries, sets `palette` to `true` (optional, default `256`)
|
||||
* `options.colors` **[number][9]** alternative spelling of `options.colours`, sets `palette` to `true` (optional, default `256`)
|
||||
* `options.dither` **[number][9]** level of Floyd-Steinberg error diffusion, sets `palette` to `true` (optional, default `1.0`)
|
||||
* `options.force` **[boolean][7]** force PNG output, otherwise attempt to use input format (optional, default `true`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -250,7 +262,7 @@ const data = await sharp(input)
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -260,17 +272,18 @@ Use these WebP options for output image.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `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.pageHeight` **[number][9]?** page height for animated output
|
||||
- `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
||||
- `options.delay` **[Array][10]<[number][9]>?** list of delays between animation frames (in milliseconds)
|
||||
- `options.force` **[boolean][7]** 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.pageHeight` **[number][9]?** page height for animated output
|
||||
* `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
||||
* `options.delay` **[Array][10]<[number][9]>?** list of delays between animation frames (in milliseconds)
|
||||
* `options.force` **[boolean][7]** force WebP output, otherwise attempt to use input format (optional, default `true`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -288,7 +301,7 @@ const outputWebp = await sharp(inputWebp, { animated: true })
|
||||
.toBuffer();
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -302,14 +315,16 @@ The prebuilt binaries do not include this - see
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][6]?** output options
|
||||
- `options.pageHeight` **[number][9]?** page height for animated output
|
||||
- `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
||||
- `options.delay` **[Array][10]<[number][9]>?** list of delays between animation frames (in milliseconds)
|
||||
- `options.force` **[boolean][7]** force GIF output, otherwise attempt to use input format (optional, default `true`)
|
||||
* `options` **[Object][6]?** output options
|
||||
|
||||
* `options.pageHeight` **[number][9]?** page height for animated output
|
||||
* `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
||||
* `options.delay` **[Array][10]<[number][9]>?** list of delays between animation frames (in milliseconds)
|
||||
* `options.force` **[boolean][7]** force GIF output, otherwise attempt to use input format (optional, default `true`)
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
<!---->
|
||||
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -319,18 +334,19 @@ Use these TIFF options for output image.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `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` **[string][2]** compression options: lzw, deflate, jpeg, ccittfax4 (optional, default `'jpeg'`)
|
||||
- `options.predictor` **[string][2]** 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` **[number][9]** horizontal tile size (optional, default `256`)
|
||||
- `options.tileHeight` **[number][9]** 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.bitdepth` **[number][9]** reduce bitdepth to 1, 2 or 4 bit (optional, default `8`)
|
||||
* `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` **[string][2]** compression options: lzw, deflate, jpeg, ccittfax4 (optional, default `'jpeg'`)
|
||||
* `options.predictor` **[string][2]** 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` **[number][9]** horizontal tile size (optional, default `256`)
|
||||
* `options.tileHeight` **[number][9]** 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.bitdepth` **[number][9]** reduce bitdepth to 1, 2 or 4 bit (optional, default `8`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -345,7 +361,7 @@ sharp('input.svg')
|
||||
.then(info => { ... });
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -358,20 +374,22 @@ most web browsers do not display these properly.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][6]?** output options
|
||||
- `options.quality` **[number][9]** quality, integer 1-100 (optional, default `50`)
|
||||
- `options.lossless` **[boolean][7]** use lossless compression (optional, default `false`)
|
||||
- `options.speed` **[number][9]** CPU effort vs file size, 0 (slowest/smallest) to 8 (fastest/largest) (optional, default `5`)
|
||||
- `options.chromaSubsampling` **[string][2]** set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling, requires libvips v8.11.0 (optional, default `'4:2:0'`)
|
||||
* `options` **[Object][6]?** output options
|
||||
|
||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `50`)
|
||||
* `options.lossless` **[boolean][7]** use lossless compression (optional, default `false`)
|
||||
* `options.speed` **[number][9]** CPU effort vs file size, 0 (slowest/smallest) to 8 (fastest/largest) (optional, default `5`)
|
||||
* `options.chromaSubsampling` **[string][2]** set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling, requires libvips v8.11.0 (optional, default `'4:2:0'`)
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
<!---->
|
||||
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.27.0
|
||||
* **since**: 0.27.0
|
||||
|
||||
## heif
|
||||
|
||||
@@ -382,21 +400,23 @@ globally-installed libvips compiled with support for libheif, libde265 and x265.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][6]?** output options
|
||||
- `options.quality` **[number][9]** quality, integer 1-100 (optional, default `50`)
|
||||
- `options.compression` **[string][2]** compression format: av1, hevc (optional, default `'av1'`)
|
||||
- `options.lossless` **[boolean][7]** use lossless compression (optional, default `false`)
|
||||
- `options.speed` **[number][9]** CPU effort vs file size, 0 (slowest/smallest) to 8 (fastest/largest) (optional, default `5`)
|
||||
- `options.chromaSubsampling` **[string][2]** set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling, requires libvips v8.11.0 (optional, default `'4:2:0'`)
|
||||
* `options` **[Object][6]?** output options
|
||||
|
||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `50`)
|
||||
* `options.compression` **[string][2]** compression format: av1, hevc (optional, default `'av1'`)
|
||||
* `options.lossless` **[boolean][7]** use lossless compression (optional, default `false`)
|
||||
* `options.speed` **[number][9]** CPU effort vs file size, 0 (slowest/smallest) to 8 (fastest/largest) (optional, default `5`)
|
||||
* `options.chromaSubsampling` **[string][2]** set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling, requires libvips v8.11.0 (optional, default `'4:2:0'`)
|
||||
|
||||
- Throws **[Error][4]** Invalid options
|
||||
<!---->
|
||||
|
||||
* Throws **[Error][4]** Invalid options
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
**Meta**
|
||||
|
||||
- **since**: 0.23.0
|
||||
* **since**: 0.23.0
|
||||
|
||||
## raw
|
||||
|
||||
@@ -435,18 +455,19 @@ Warning: multiple sharp instances concurrently producing tile output can expose
|
||||
|
||||
### Parameters
|
||||
|
||||
- `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.background` **([string][2] \| [Object][6])** background colour, parsed by the [color][12] module, defaults to white without transparency. (optional, default `{r:255,g:255,b:255,alpha:1}`)
|
||||
- `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`, `iiif`, `zoomify` or `google`. (optional, default `'dz'`)
|
||||
- `options.centre` **[boolean][7]** centre image in tile. (optional, default `false`)
|
||||
- `options.center` **[boolean][7]** alternative spelling of centre. (optional, default `false`)
|
||||
- `options.id` **[string][2]** when `layout` is `iiif`, sets the `@id` attribute of `info.json` (optional, default `'https://example.com/iiif'`)
|
||||
* `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.background` **([string][2] | [Object][6])** background colour, parsed by the [color][12] module, defaults to white without transparency. (optional, default `{r:255,g:255,b:255,alpha:1}`)
|
||||
* `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`, `iiif`, `zoomify` or `google`. (optional, default `'dz'`)
|
||||
* `options.centre` **[boolean][7]** centre image in tile. (optional, default `false`)
|
||||
* `options.center` **[boolean][7]** alternative spelling of centre. (optional, default `false`)
|
||||
* `options.id` **[string][2]** when `layout` is `iiif`, sets the `@id` attribute of `info.json` (optional, default `'https://example.com/iiif'`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -462,7 +483,7 @@ sharp('input.tiff')
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][4]** Invalid parameters
|
||||
* Throws **[Error][4]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
|
||||
@@ -6,49 +6,50 @@ Resize image to `width`, `height` or `width x height`.
|
||||
|
||||
When both a `width` and `height` are provided, the possible methods by which the image should **fit** these are:
|
||||
|
||||
- `cover`: (default) Preserving aspect ratio, ensure the image covers both provided dimensions by cropping/clipping to fit.
|
||||
- `contain`: Preserving aspect ratio, contain within both provided dimensions using "letterboxing" where necessary.
|
||||
- `fill`: Ignore the aspect ratio of the input and stretch to both provided dimensions.
|
||||
- `inside`: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified.
|
||||
- `outside`: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified.
|
||||
* `cover`: (default) Preserving aspect ratio, ensure the image covers both provided dimensions by cropping/clipping to fit.
|
||||
* `contain`: Preserving aspect ratio, contain within both provided dimensions using "letterboxing" where necessary.
|
||||
* `fill`: Ignore the aspect ratio of the input and stretch to both provided dimensions.
|
||||
* `inside`: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified.
|
||||
* `outside`: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified.
|
||||
|
||||
Some of these values are based on the [object-fit][1] CSS property.
|
||||
|
||||
When using a `fit` of `cover` or `contain`, the default **position** is `centre`. Other options are:
|
||||
|
||||
- `sharp.position`: `top`, `right top`, `right`, `right bottom`, `bottom`, `left bottom`, `left`, `left top`.
|
||||
- `sharp.gravity`: `north`, `northeast`, `east`, `southeast`, `south`, `southwest`, `west`, `northwest`, `center` or `centre`.
|
||||
- `sharp.strategy`: `cover` only, dynamically crop using either the `entropy` or `attention` strategy.
|
||||
* `sharp.position`: `top`, `right top`, `right`, `right bottom`, `bottom`, `left bottom`, `left`, `left top`.
|
||||
* `sharp.gravity`: `north`, `northeast`, `east`, `southeast`, `south`, `southwest`, `west`, `northwest`, `center` or `centre`.
|
||||
* `sharp.strategy`: `cover` only, dynamically crop using either the `entropy` or `attention` strategy.
|
||||
|
||||
Some of these values are based on the [object-position][2] CSS property.
|
||||
|
||||
The experimental strategy-based approach resizes so one dimension is at its target length
|
||||
then repeatedly ranks edge regions, discarding the edge with the lowest score based on the selected strategy.
|
||||
|
||||
- `entropy`: focus on the region with the highest [Shannon entropy][3].
|
||||
- `attention`: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones.
|
||||
* `entropy`: focus on the region with the highest [Shannon entropy][3].
|
||||
* `attention`: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones.
|
||||
|
||||
Possible interpolation kernels are:
|
||||
|
||||
- `nearest`: Use [nearest neighbour interpolation][4].
|
||||
- `cubic`: Use a [Catmull-Rom spline][5].
|
||||
- `mitchell`: Use a [Mitchell-Netravali spline][6].
|
||||
- `lanczos2`: Use a [Lanczos kernel][7] with `a=2`.
|
||||
- `lanczos3`: Use a Lanczos kernel with `a=3` (the default).
|
||||
* `nearest`: Use [nearest neighbour interpolation][4].
|
||||
* `cubic`: Use a [Catmull-Rom spline][5].
|
||||
* `mitchell`: Use a [Mitchell-Netravali spline][6].
|
||||
* `lanczos2`: Use a [Lanczos kernel][7] with `a=2`.
|
||||
* `lanczos3`: Use a Lanczos kernel with `a=3` (the default).
|
||||
|
||||
### Parameters
|
||||
|
||||
- `width` **[number][8]?** pixels wide the resultant image should be. Use `null` or `undefined` to auto-scale the width to match the height.
|
||||
- `height` **[number][8]?** pixels high the resultant image should be. Use `null` or `undefined` to auto-scale the height to match the width.
|
||||
- `options` **[Object][9]?**
|
||||
- `options.width` **[String][10]?** alternative means of specifying `width`. If both are present this take priority.
|
||||
- `options.height` **[String][10]?** alternative means of specifying `height`. If both are present this take priority.
|
||||
- `options.fit` **[String][10]** how the image should be resized to fit both provided dimensions, one of `cover`, `contain`, `fill`, `inside` or `outside`. (optional, default `'cover'`)
|
||||
- `options.position` **[String][10]** position, gravity or strategy to use when `fit` is `cover` or `contain`. (optional, default `'centre'`)
|
||||
- `options.background` **([String][10] \| [Object][9])** background colour when using a `fit` of `contain`, parsed by the [color][11] module, defaults to black without transparency. (optional, default `{r:0,g:0,b:0,alpha:1}`)
|
||||
- `options.kernel` **[String][10]** the kernel to use for image reduction. (optional, default `'lanczos3'`)
|
||||
- `options.withoutEnlargement` **[Boolean][12]** do not enlarge if the width _or_ height are already less than the specified dimensions, equivalent to GraphicsMagick's `>` geometry option. (optional, default `false`)
|
||||
- `options.fastShrinkOnLoad` **[Boolean][12]** take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern on some images. (optional, default `true`)
|
||||
* `width` **[number][8]?** pixels wide the resultant image should be. Use `null` or `undefined` to auto-scale the width to match the height.
|
||||
* `height` **[number][8]?** pixels high the resultant image should be. Use `null` or `undefined` to auto-scale the height to match the width.
|
||||
* `options` **[Object][9]?**
|
||||
|
||||
* `options.width` **[String][10]?** alternative means of specifying `width`. If both are present this take priority.
|
||||
* `options.height` **[String][10]?** alternative means of specifying `height`. If both are present this take priority.
|
||||
* `options.fit` **[String][10]** how the image should be resized to fit both provided dimensions, one of `cover`, `contain`, `fill`, `inside` or `outside`. (optional, default `'cover'`)
|
||||
* `options.position` **[String][10]** position, gravity or strategy to use when `fit` is `cover` or `contain`. (optional, default `'centre'`)
|
||||
* `options.background` **([String][10] | [Object][9])** background colour when using a `fit` of `contain`, parsed by the [color][11] module, defaults to black without transparency. (optional, default `{r:0,g:0,b:0,alpha:1}`)
|
||||
* `options.kernel` **[String][10]** the kernel to use for image reduction. (optional, default `'lanczos3'`)
|
||||
* `options.withoutEnlargement` **[Boolean][12]** do not enlarge if the width *or* height are already less than the specified dimensions, equivalent to GraphicsMagick's `>` geometry option. (optional, default `false`)
|
||||
* `options.fastShrinkOnLoad` **[Boolean][12]** take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern on some images. (optional, default `true`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -125,7 +126,7 @@ const scaleByHalf = await sharp(input)
|
||||
);
|
||||
```
|
||||
|
||||
- Throws **[Error][13]** Invalid parameters
|
||||
* Throws **[Error][13]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -136,12 +137,13 @@ This operation will always occur after resizing and extraction, if any.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `extend` **([number][8] \| [Object][9])** single pixel count to add to all edges or an Object with per-edge counts
|
||||
- `extend.top` **[number][8]** (optional, default `0`)
|
||||
- `extend.left` **[number][8]** (optional, default `0`)
|
||||
- `extend.bottom` **[number][8]** (optional, default `0`)
|
||||
- `extend.right` **[number][8]** (optional, default `0`)
|
||||
- `extend.background` **([String][10] \| [Object][9])** background colour, parsed by the [color][11] module, defaults to black without transparency. (optional, default `{r:0,g:0,b:0,alpha:1}`)
|
||||
* `extend` **([number][8] | [Object][9])** single pixel count to add to all edges or an Object with per-edge counts
|
||||
|
||||
* `extend.top` **[number][8]** (optional, default `0`)
|
||||
* `extend.left` **[number][8]** (optional, default `0`)
|
||||
* `extend.bottom` **[number][8]** (optional, default `0`)
|
||||
* `extend.right` **[number][8]** (optional, default `0`)
|
||||
* `extend.background` **([String][10] | [Object][9])** background colour, parsed by the [color][11] module, defaults to black without transparency. (optional, default `{r:0,g:0,b:0,alpha:1}`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -170,7 +172,7 @@ sharp(input)
|
||||
...
|
||||
```
|
||||
|
||||
- Throws **[Error][13]** Invalid parameters
|
||||
* Throws **[Error][13]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -178,17 +180,18 @@ Returns **Sharp**
|
||||
|
||||
Extract/crop a region of the image.
|
||||
|
||||
- Use `extract` before `resize` for pre-resize extraction.
|
||||
- Use `extract` after `resize` for post-resize extraction.
|
||||
- Use `extract` before and after for both.
|
||||
* Use `extract` before `resize` for pre-resize extraction.
|
||||
* Use `extract` after `resize` for post-resize extraction.
|
||||
* Use `extract` before and after for both.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **[Object][9]** describes the region to extract using integral pixel values
|
||||
- `options.left` **[number][8]** zero-indexed offset from left edge
|
||||
- `options.top` **[number][8]** zero-indexed offset from top edge
|
||||
- `options.width` **[number][8]** width of region to extract
|
||||
- `options.height` **[number][8]** height of region to extract
|
||||
* `options` **[Object][9]** describes the region to extract using integral pixel values
|
||||
|
||||
* `options.left` **[number][8]** zero-indexed offset from left edge
|
||||
* `options.top` **[number][8]** zero-indexed offset from top edge
|
||||
* `options.width` **[number][8]** width of region to extract
|
||||
* `options.height` **[number][8]** height of region to extract
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -210,7 +213,7 @@ sharp(input)
|
||||
});
|
||||
```
|
||||
|
||||
- Throws **[Error][13]** Invalid parameters
|
||||
* Throws **[Error][13]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
@@ -224,10 +227,11 @@ will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `threshold` **[number][8]** the allowed difference from the top-left pixel, a number greater than zero. (optional, default `10`)
|
||||
* `threshold` **[number][8]** the allowed difference from the top-left pixel, a number greater than zero. (optional, default `10`)
|
||||
|
||||
<!---->
|
||||
|
||||
- Throws **[Error][13]** Invalid parameters
|
||||
* Throws **[Error][13]** Invalid parameters
|
||||
|
||||
Returns **Sharp**
|
||||
|
||||
|
||||
@@ -54,17 +54,18 @@ console.log(sharp.versions);
|
||||
|
||||
## cache
|
||||
|
||||
Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
|
||||
Gets or, when options are provided, sets the limits of *libvips'* operation cache.
|
||||
Existing entries in the cache will be trimmed after any change in limits.
|
||||
This method always returns cache statistics,
|
||||
useful for determining how much working memory is required for a particular task.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` **([Object][1] \| [boolean][10])** Object with the following attributes, or boolean where true uses default cache settings and false removes all caching (optional, default `true`)
|
||||
- `options.memory` **[number][11]** is the maximum memory in MB to use for this cache (optional, default `50`)
|
||||
- `options.files` **[number][11]** is the maximum number of files to hold open (optional, default `20`)
|
||||
- `options.items` **[number][11]** is the maximum number of operations to cache (optional, default `100`)
|
||||
* `options` **([Object][1] | [boolean][10])** Object with the following attributes, or boolean where true uses default cache settings and false removes all caching (optional, default `true`)
|
||||
|
||||
* `options.memory` **[number][11]** is the maximum memory in MB to use for this cache (optional, default `50`)
|
||||
* `options.files` **[number][11]** is the maximum number of files to hold open (optional, default `20`)
|
||||
* `options.items` **[number][11]** is the maximum number of operations to cache (optional, default `100`)
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -83,7 +84,7 @@ Returns **[Object][1]**
|
||||
## concurrency
|
||||
|
||||
Gets or, when a concurrency is provided, sets
|
||||
the number of threads _libvips'_ should create to process each image.
|
||||
the number of threads *libvips'* should create to process each image.
|
||||
|
||||
The default value is the number of CPU cores,
|
||||
except when using glibc-based Linux without jemalloc,
|
||||
@@ -98,7 +99,7 @@ This method always returns the current concurrency.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `concurrency` **[number][11]?**
|
||||
* `concurrency` **[number][11]?**
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -114,8 +115,8 @@ Returns **[number][11]** concurrency
|
||||
|
||||
An EventEmitter that emits a `change` event when a task is either:
|
||||
|
||||
- queued, waiting for _libuv_ to provide a worker thread
|
||||
- complete
|
||||
* queued, waiting for *libuv* to provide a worker thread
|
||||
* complete
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -129,8 +130,8 @@ sharp.queue.on('change', function(queueLength) {
|
||||
|
||||
Provides access to internal task counters.
|
||||
|
||||
- queue is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool.
|
||||
- process is the number of resize tasks currently being processed.
|
||||
* queue is the number of tasks this module has queued waiting for *libuv* to provide a worker thread from its pool.
|
||||
* process is the number of resize tasks currently being processed.
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -150,7 +151,7 @@ by taking advantage of the SIMD vector unit of the CPU, e.g. Intel SSE and ARM N
|
||||
|
||||
### Parameters
|
||||
|
||||
- `simd` **[boolean][10]** (optional, default `true`)
|
||||
* `simd` **[boolean][10]** (optional, default `true`)
|
||||
|
||||
### Examples
|
||||
|
||||
|
||||
@@ -4,6 +4,41 @@
|
||||
|
||||
Requires libvips v8.10.6
|
||||
|
||||
### v0.28.3 - 24th May 2021
|
||||
|
||||
* Ensure presence of libvips, vendored or global, before invoking node-gyp.
|
||||
|
||||
* Skip shrink-on-load for multi-page WebP.
|
||||
[#2714](https://github.com/lovell/sharp/issues/2714)
|
||||
|
||||
* Add contrast limiting adaptive histogram equalization (CLAHE) operator.
|
||||
[#2726](https://github.com/lovell/sharp/pull/2726)
|
||||
[@baparham](https://github.com/baparham)
|
||||
|
||||
### v0.28.2 - 10th May 2021
|
||||
|
||||
* Allow `withMetadata` to set `density`.
|
||||
[#967](https://github.com/lovell/sharp/issues/967)
|
||||
|
||||
* Skip shrink-on-load where one dimension <4px.
|
||||
[#2653](https://github.com/lovell/sharp/issues/2653)
|
||||
|
||||
* Allow escaped proxy credentials.
|
||||
[#2664](https://github.com/lovell/sharp/pull/2664)
|
||||
[@msalettes](https://github.com/msalettes)
|
||||
|
||||
* Add `premultiplied` flag for raw pixel data input.
|
||||
[#2685](https://github.com/lovell/sharp/pull/2685)
|
||||
[@mnutt](https://github.com/mnutt)
|
||||
|
||||
* Detect empty input and throw a helpful error.
|
||||
[#2687](https://github.com/lovell/sharp/pull/2687)
|
||||
[@JakobJingleheimer](https://github.com/JakobJingleheimer)
|
||||
|
||||
* Add install-time flag to skip version compatibility checks.
|
||||
[#2692](https://github.com/lovell/sharp/pull/2692)
|
||||
[@xemle](https://github.com/xemle)
|
||||
|
||||
### v0.28.1 - 5th April 2021
|
||||
|
||||
* Ensure all installation errors are logged with a more obvious prefix.
|
||||
|
||||
@@ -209,3 +209,6 @@ GitHub: https://github.com/beig
|
||||
|
||||
Name: Florian Busch
|
||||
GitHub: https://github.com/florian-busch
|
||||
|
||||
Name: Matthieu Salettes
|
||||
GitHub: https://github.com/msalettes
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="https://pixel.plumbing/px/72x72/sharp-logo.svg">
|
||||
<link rel="apple-touch-icon-precomposed" href="https://pixel.plumbing/px/57x57/sharp-logo.svg">
|
||||
<link rel="author" href="/humans.txt" type="text/plain">
|
||||
<link rel="preload" href="https://cdn.jsdelivr.net/gh/lovell/sharp@v0.28.1/docs/README.md" as="fetch" type="text/markdown" crossorigin>
|
||||
<link rel="preload" href="https://cdn.jsdelivr.net/gh/lovell/sharp@v0.28.3/docs/README.md" as="fetch" type="text/markdown" crossorigin>
|
||||
<link rel="preload" href="https://cdn.jsdelivr.net/gh/lovell/sharp@master/docs/image/sharp-logo.svg" as="image" type="image/svg+xml" crossorigin>
|
||||
<link rel="dns-prefetch" href="https://pixel.plumbing">
|
||||
<link rel="dns-prefetch" href="https://www.google-analytics.com">
|
||||
@@ -139,7 +139,7 @@
|
||||
docuteApiTitlePlugin,
|
||||
docuteApiSearchPlugin
|
||||
],
|
||||
sourcePath: 'https://cdn.jsdelivr.net/gh/lovell/sharp@v0.28.1/docs',
|
||||
sourcePath: 'https://cdn.jsdelivr.net/gh/lovell/sharp@v0.28.3/docs',
|
||||
nav: [
|
||||
{
|
||||
title: 'Funding',
|
||||
|
||||
@@ -49,6 +49,7 @@ The following platforms require compilation of both libvips and sharp from sourc
|
||||
|
||||
The architecture and platform of Node.js used for `npm install`
|
||||
must be the same as the architecture and platform of Node.js used at runtime.
|
||||
See the [cross-platform](#cross-platform) section if this is not the case.
|
||||
|
||||
When using npm v6 or earlier, the `npm install --unsafe-perm` flag must be used when installing as `root` or a `sudo` user.
|
||||
|
||||
@@ -70,6 +71,33 @@ When this new ARM64 CPU is made freely available
|
||||
to open source projects via a CI service
|
||||
then prebuilt sharp binaries can also be provided.
|
||||
|
||||
## Cross-platform
|
||||
|
||||
At `npm install` time, prebuilt binaries are automatically selected for the
|
||||
current OS platform and CPU architecture, where available.
|
||||
|
||||
The target platform and/or architecture can be manually selected using the following flags.
|
||||
|
||||
```sh
|
||||
npm install --platform=... --arch=... --arm-version=... sharp
|
||||
```
|
||||
|
||||
* `--platform`: one of `linux`, `linuxmusl`, `darwin` or `win32`.
|
||||
* `--arch`: one of `x64`, `ia32`, `arm` or `arm64`.
|
||||
* `--arm-version`: one of `6`, `7` or `8` (`arm` defaults to `6`, `arm64` defaults to `8`).
|
||||
* `--sharp-install-force`: skip version compatibility checks.
|
||||
|
||||
These values can also be set via environment variables,
|
||||
`npm_config_platform`, `npm_config_arch`, `npm_config_arm_version`
|
||||
and `SHARP_INSTALL_FORCE` respectively.
|
||||
|
||||
For example, if the target machine has a 64-bit ARM CPU and is running Alpine Linux,
|
||||
use the following flags:
|
||||
|
||||
```sh
|
||||
npm install --arch=arm64 --platform=linuxmusl sharp
|
||||
```
|
||||
|
||||
## Custom libvips
|
||||
|
||||
To use a custom, globally-installed version of libvips instead of the provided binaries,
|
||||
@@ -123,7 +151,7 @@ See the Chinese mirror below for a further example.
|
||||
|
||||
## Chinese mirror
|
||||
|
||||
Alibaba provide a mirror site based in China containing binaries for both sharp and libvips.
|
||||
A mirror site based in China, provided by Alibaba, contains binaries for both sharp and libvips.
|
||||
|
||||
To use this either set the following configuration:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { extractDescription, extractKeywords } = require('./extract');
|
||||
const { extractDescription, extractKeywords, extractParameters } = require('./extract');
|
||||
|
||||
const searchIndex = [];
|
||||
|
||||
@@ -37,18 +37,19 @@ for (const match of matches) {
|
||||
].forEach((section) => {
|
||||
const contents = fs.readFileSync(path.join(__dirname, '..', `api-${section}.md`), 'utf8');
|
||||
const matches = contents.matchAll(
|
||||
/\n## (?<title>[A-Za-z]+)\n\n(?<firstparagraph>.+?)\n\n/gs
|
||||
/\n## (?<title>[A-Za-z]+)\n\n(?<firstparagraph>.+?)\n\n(?<parameters>### Parameters.+?Returns)?/gs
|
||||
);
|
||||
for (const match of matches) {
|
||||
const { title, firstparagraph } = match.groups;
|
||||
const { title, firstparagraph, parameters } = match.groups;
|
||||
const description = firstparagraph.startsWith('###')
|
||||
? 'Constructor'
|
||||
: extractDescription(firstparagraph);
|
||||
const parameterNames = parameters ? extractParameters(parameters) : '';
|
||||
|
||||
searchIndex.push({
|
||||
t: title,
|
||||
d: description,
|
||||
k: extractKeywords(`${title} ${description}`),
|
||||
k: extractKeywords(`${title} ${description} ${parameterNames}`),
|
||||
l: `/api-${section}#${title.toLowerCase()}`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ const stopWords = require('./stop-words');
|
||||
|
||||
const extractDescription = (str) =>
|
||||
str
|
||||
.replace(/### Examples.*/sg, '')
|
||||
.replace(/\(http[^)]+/g, '')
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/[^A-Za-z0-9_/\-,. ]/g, '')
|
||||
@@ -11,6 +12,11 @@ const extractDescription = (str) =>
|
||||
.substr(0, 180)
|
||||
.trim();
|
||||
|
||||
const extractParameters = (str) =>
|
||||
[...str.matchAll(/options\.(?<name>[^.`]+)/gs)]
|
||||
.map((match) => match.groups.name)
|
||||
.join(' ');
|
||||
|
||||
const extractKeywords = (str) =>
|
||||
[
|
||||
...new Set(
|
||||
@@ -21,4 +27,4 @@ const extractKeywords = (str) =>
|
||||
)
|
||||
].join(' ');
|
||||
|
||||
module.exports = { extractDescription, extractKeywords };
|
||||
module.exports = { extractDescription, extractKeywords, extractParameters };
|
||||
|
||||
@@ -17,6 +17,7 @@ module.exports = [
|
||||
'before',
|
||||
'both',
|
||||
'call',
|
||||
'callback',
|
||||
'can',
|
||||
'containing',
|
||||
'default',
|
||||
@@ -26,6 +27,7 @@ module.exports = [
|
||||
'ensure',
|
||||
'etc',
|
||||
'every',
|
||||
'except',
|
||||
'for',
|
||||
'from',
|
||||
'get',
|
||||
@@ -49,12 +51,16 @@ module.exports = [
|
||||
'occur',
|
||||
'occurs',
|
||||
'options',
|
||||
'other',
|
||||
'out',
|
||||
'over',
|
||||
'perform',
|
||||
'performs',
|
||||
'provide',
|
||||
'provided',
|
||||
'ready',
|
||||
'requires',
|
||||
'returned',
|
||||
'same',
|
||||
'see',
|
||||
'set',
|
||||
@@ -67,9 +73,11 @@ module.exports = [
|
||||
'supported',
|
||||
'sure',
|
||||
'take',
|
||||
'than',
|
||||
'that',
|
||||
'the',
|
||||
'their',
|
||||
'then',
|
||||
'there',
|
||||
'therefore',
|
||||
'these',
|
||||
|
||||
11
install/can-compile.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const libvips = require('../lib/libvips');
|
||||
|
||||
try {
|
||||
if (!(libvips.useGlobalLibvips() || libvips.hasVendoredLibvips())) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
} catch (err) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
@@ -7,7 +7,8 @@ const stream = require('stream');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const detectLibc = require('detect-libc');
|
||||
const semver = require('semver');
|
||||
const semverLessThan = require('semver/functions/lt');
|
||||
const semverSatisfies = require('semver/functions/satisfies');
|
||||
const simpleGet = require('simple-get');
|
||||
const tarFs = require('tar-fs');
|
||||
|
||||
@@ -35,17 +36,25 @@ const { minimumLibvipsVersion, minimumLibvipsVersionLabelled } = libvips;
|
||||
const distHost = process.env.npm_config_sharp_libvips_binary_host || 'https://github.com/lovell/sharp-libvips/releases/download';
|
||||
const distBaseUrl = process.env.npm_config_sharp_dist_base_url || process.env.SHARP_DIST_BASE_URL || `${distHost}/v${minimumLibvipsVersionLabelled}/`;
|
||||
const supportsBrotli = ('BrotliDecompress' in zlib);
|
||||
const installationForced = !!(process.env.npm_config_sharp_install_force || process.env.SHARP_INSTALL_FORCE);
|
||||
|
||||
const fail = function (err) {
|
||||
libvips.log(err);
|
||||
if (err.code === 'EACCES') {
|
||||
libvips.log('Are you trying to install as a root or sudo user? Try again with the --unsafe-perm flag');
|
||||
}
|
||||
libvips.log('Attempting to build from source via node-gyp but this may fail due to the above error');
|
||||
libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
const handleError = function (err) {
|
||||
if (installationForced) {
|
||||
libvips.log(`Installation warning: ${err.message}`);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
const extractTarball = function (tarPath, platformAndArch) {
|
||||
const vendorPath = path.join(__dirname, '..', 'vendor');
|
||||
libvips.mkdirSync(vendorPath);
|
||||
@@ -95,20 +104,21 @@ try {
|
||||
if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') {
|
||||
throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
}
|
||||
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version) {
|
||||
if (semver.lt(`${detectLibc.version}.0`, `${minimumGlibcVersionByArch[arch]}.0`)) {
|
||||
throw new Error(`Use with glibc ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
// Linux libc version check
|
||||
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && minimumGlibcVersionByArch[arch]) {
|
||||
if (semverLessThan(`${detectLibc.version}.0`, `${minimumGlibcVersionByArch[arch]}.0`)) {
|
||||
handleError(new Error(`Use with glibc ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
|
||||
}
|
||||
}
|
||||
if (detectLibc.family === detectLibc.MUSL && detectLibc.version) {
|
||||
if (semver.lt(detectLibc.version, '1.1.24')) {
|
||||
throw new Error(`Use with musl ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
if (semverLessThan(detectLibc.version, '1.1.24')) {
|
||||
handleError(new Error(`Use with musl ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
|
||||
}
|
||||
}
|
||||
|
||||
// Node.js minimum version check
|
||||
const supportedNodeVersion = process.env.npm_package_engines_node || require('../package.json').engines.node;
|
||||
if (!semver.satisfies(process.versions.node, supportedNodeVersion)) {
|
||||
throw new Error(`Expected Node.js version ${supportedNodeVersion} but found ${process.versions.node}`);
|
||||
if (!semverSatisfies(process.versions.node, supportedNodeVersion)) {
|
||||
handleError(new Error(`Expected Node.js version ${supportedNodeVersion} but found ${process.versions.node}`));
|
||||
}
|
||||
|
||||
const extension = supportsBrotli ? 'br' : 'gz';
|
||||
|
||||
@@ -25,7 +25,7 @@ module.exports = function () {
|
||||
? tunnelAgent.httpsOverHttps
|
||||
: tunnelAgent.httpsOverHttp;
|
||||
const proxyAuth = proxy.username && proxy.password
|
||||
? `${proxy.username}:${proxy.password}`
|
||||
? `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`
|
||||
: null;
|
||||
return tunnel({
|
||||
proxy: {
|
||||
|
||||
@@ -15,6 +15,8 @@ const bool = {
|
||||
/**
|
||||
* Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.
|
||||
*
|
||||
* See also {@link /api-operation#flatten|flatten}.
|
||||
*
|
||||
* @example
|
||||
* sharp('rgba.png')
|
||||
* .removeAlpha()
|
||||
|
||||
@@ -89,6 +89,8 @@ const blend = {
|
||||
* @param {Number} [images[].raw.width]
|
||||
* @param {Number} [images[].raw.height]
|
||||
* @param {Number} [images[].raw.channels]
|
||||
* @param {boolean} [images[].failOnError=true] - @see {@link /api-constructor#parameters|constructor parameters}
|
||||
* @param {number|boolean} [images[].limitInputPixels=268402689] - @see {@link /api-constructor#parameters|constructor parameters}
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid parameters
|
||||
*/
|
||||
|
||||
@@ -139,6 +139,8 @@ const debuglog = util.debuglog('sharp');
|
||||
* @param {number} [options.raw.width] - integral number of pixels wide.
|
||||
* @param {number} [options.raw.height] - integral number of pixels high.
|
||||
* @param {number} [options.raw.channels] - integral number of channels, between 1 and 4.
|
||||
* @param {boolean} [options.raw.premultiplied] - specifies that the raw input has already been premultiplied, set to `true`
|
||||
* to avoid sharp premultiplying the image. (optional, default `false`)
|
||||
* @param {Object} [options.create] - describes a new image to be created.
|
||||
* @param {number} [options.create.width] - integral number of pixels wide.
|
||||
* @param {number} [options.create.height] - integral number of pixels high.
|
||||
@@ -214,6 +216,9 @@ const Sharp = function (input, options) {
|
||||
gammaOut: 0,
|
||||
greyscale: false,
|
||||
normalise: false,
|
||||
claheWidth: 0,
|
||||
claheHeight: 0,
|
||||
claheMaxSlope: 3,
|
||||
brightness: 1,
|
||||
saturation: 1,
|
||||
hue: 0,
|
||||
@@ -231,6 +236,7 @@ const Sharp = function (input, options) {
|
||||
streamOut: false,
|
||||
withMetadata: false,
|
||||
withMetadataOrientation: -1,
|
||||
withMetadataDensity: 0,
|
||||
withMetadataIcc: '',
|
||||
withMetadataStrs: {},
|
||||
resolveWithObject: false,
|
||||
|
||||
@@ -30,9 +30,15 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
inputDescriptor.file = input;
|
||||
} else if (is.buffer(input)) {
|
||||
// Buffer
|
||||
if (input.length === 0) {
|
||||
throw Error('Input Buffer is empty');
|
||||
}
|
||||
inputDescriptor.buffer = input;
|
||||
} else if (is.uint8Array(input)) {
|
||||
// Uint8Array or Uint8ClampedArray
|
||||
if (input.length === 0) {
|
||||
throw Error('Input Bit Array is empty');
|
||||
}
|
||||
inputDescriptor.buffer = Buffer.from(input.buffer);
|
||||
} else if (is.plainObject(input) && !is.defined(inputOptions)) {
|
||||
// Plain Object descriptor, e.g. create
|
||||
@@ -97,6 +103,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
inputDescriptor.rawWidth = inputOptions.raw.width;
|
||||
inputDescriptor.rawHeight = inputOptions.raw.height;
|
||||
inputDescriptor.rawChannels = inputOptions.raw.channels;
|
||||
inputDescriptor.rawPremultiplied = !!inputOptions.raw.premultiplied;
|
||||
} else {
|
||||
throw new Error('Expected width, height and channels for raw pixel input');
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@ const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const spawnSync = require('child_process').spawnSync;
|
||||
const semver = require('semver');
|
||||
const semverCoerce = require('semver/functions/coerce');
|
||||
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
||||
|
||||
const platform = require('./platform');
|
||||
|
||||
const env = process.env;
|
||||
const minimumLibvipsVersionLabelled = env.npm_package_config_libvips || /* istanbul ignore next */
|
||||
require('../package.json').config.libvips;
|
||||
const minimumLibvipsVersion = semver.coerce(minimumLibvipsVersionLabelled).version;
|
||||
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
||||
|
||||
const spawnSyncOptions = {
|
||||
encoding: 'utf8',
|
||||
@@ -105,7 +107,7 @@ const useGlobalLibvips = function () {
|
||||
}
|
||||
const globalVipsVersion = globalLibvipsVersion();
|
||||
return !!globalVipsVersion && /* istanbul ignore next */
|
||||
semver.gte(globalVipsVersion, minimumLibvipsVersion);
|
||||
semverGreaterThanOrEqualTo(globalVipsVersion, minimumLibvipsVersion);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -270,9 +270,11 @@ function blur (sigma) {
|
||||
/**
|
||||
* Merge alpha transparency channel, if any, with a background, then remove the alpha channel.
|
||||
*
|
||||
* See also {@link /api-channel#removealpha|removeAlpha}.
|
||||
*
|
||||
* @example
|
||||
* await sharp(rgbaInput)
|
||||
* .flatten('#F0A703')
|
||||
* .flatten({ background: '#F0A703' })
|
||||
* .toBuffer();
|
||||
*
|
||||
* @param {Object} [options]
|
||||
@@ -350,6 +352,47 @@ function normalize (normalize) {
|
||||
return this.normalise(normalize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform contrast limiting adaptive histogram equalization
|
||||
* {@link https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE|CLAHE}.
|
||||
*
|
||||
* This will, in general, enhance the clarity of the image by bringing out darker details.
|
||||
*
|
||||
* @since 0.28.3
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {number} options.width - integer width of the region in pixels.
|
||||
* @param {number} options.height - integer height of the region in pixels.
|
||||
* @param {number} [options.maxSlope=3] - maximum value for the slope of the
|
||||
* cumulative histogram. A value of 0 disables contrast limiting. Valid values
|
||||
* are integers in the range 0-100 (inclusive)
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid parameters
|
||||
*/
|
||||
function clahe (options) {
|
||||
if (!is.plainObject(options)) {
|
||||
throw is.invalidParameterError('options', 'plain object', options);
|
||||
}
|
||||
if (!('width' in options) || !is.integer(options.width) || options.width <= 0) {
|
||||
throw is.invalidParameterError('width', 'integer above zero', options.width);
|
||||
} else {
|
||||
this.options.claheWidth = options.width;
|
||||
}
|
||||
if (!('height' in options) || !is.integer(options.height) || options.height <= 0) {
|
||||
throw is.invalidParameterError('height', 'integer above zero', options.height);
|
||||
} else {
|
||||
this.options.claheHeight = options.height;
|
||||
}
|
||||
if (!is.defined(options.maxSlope)) {
|
||||
this.options.claheMaxSlope = 3;
|
||||
} else if (!is.integer(options.maxSlope) || options.maxSlope < 0 || options.maxSlope > 100) {
|
||||
throw is.invalidParameterError('maxSlope', 'integer 0-100', options.maxSlope);
|
||||
} else {
|
||||
this.options.claheMaxSlope = options.maxSlope;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convolve the image with the specified kernel.
|
||||
*
|
||||
@@ -368,7 +411,7 @@ function normalize (normalize) {
|
||||
*
|
||||
* @param {Object} kernel
|
||||
* @param {number} kernel.width - width of the kernel in pixels.
|
||||
* @param {number} kernel.height - width of the kernel in pixels.
|
||||
* @param {number} kernel.height - height of the kernel in pixels.
|
||||
* @param {Array<number>} kernel.kernel - Array of length `width*height` containing the kernel values.
|
||||
* @param {number} [kernel.scale=sum] - the scale of the kernel in pixels.
|
||||
* @param {number} [kernel.offset=0] - the offset of the kernel in pixels.
|
||||
@@ -594,6 +637,7 @@ module.exports = function (Sharp) {
|
||||
negate,
|
||||
normalise,
|
||||
normalize,
|
||||
clahe,
|
||||
convolve,
|
||||
threshold,
|
||||
boolean,
|
||||
|
||||
@@ -150,7 +150,7 @@ function toBuffer (options, callback) {
|
||||
*
|
||||
* @example
|
||||
* // Set "IFD0-Copyright" in output EXIF metadata
|
||||
* await sharp(input)
|
||||
* const data = await sharp(input)
|
||||
* .withMetadata({
|
||||
* exif: {
|
||||
* IFD0: {
|
||||
@@ -160,10 +160,17 @@ function toBuffer (options, callback) {
|
||||
* })
|
||||
* .toBuffer();
|
||||
*
|
||||
* * @example
|
||||
* // Set output metadata to 96 DPI
|
||||
* const data = await sharp(input)
|
||||
* .withMetadata({ density: 96 })
|
||||
* .toBuffer();
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @param {number} [options.orientation] value between 1 and 8, used to update the EXIF `Orientation` tag.
|
||||
* @param {string} [options.icc] filesystem path to output ICC profile, defaults to sRGB.
|
||||
* @param {Object<Object>} [options.exif={}] Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
||||
* @param {number} [options.density] Number of pixels per inch (DPI).
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid parameters
|
||||
*/
|
||||
@@ -177,6 +184,13 @@ function withMetadata (options) {
|
||||
throw is.invalidParameterError('orientation', 'integer between 1 and 8', options.orientation);
|
||||
}
|
||||
}
|
||||
if (is.defined(options.density)) {
|
||||
if (is.number(options.density) && options.density > 0) {
|
||||
this.options.withMetadataDensity = options.density;
|
||||
} else {
|
||||
throw is.invalidParameterError('density', 'positive number', options.density);
|
||||
}
|
||||
}
|
||||
if (is.defined(options.icc)) {
|
||||
if (is.string(options.icc)) {
|
||||
this.options.withMetadataIcc = options.icc;
|
||||
|
||||
22
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images",
|
||||
"version": "0.28.1",
|
||||
"version": "0.28.3",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://github.com/lovell/sharp",
|
||||
"contributors": [
|
||||
@@ -74,12 +74,16 @@
|
||||
"Christian Flintrup <chr@gigahost.dk>",
|
||||
"Manan Jadhav <manan@motionden.com>",
|
||||
"Leon Radley <leon@radley.se>",
|
||||
"alza54 <alza54@thiocod.in>"
|
||||
"alza54 <alza54@thiocod.in>",
|
||||
"Jacob Smith <jacob@frende.me>",
|
||||
"Michael Nutt <michael@nutt.im>",
|
||||
"Brad Parham <baparham@gmail.com>"
|
||||
],
|
||||
"scripts": {
|
||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
|
||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
|
||||
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
|
||||
"test": "semistandard && cpplint && npm run test-unit && npm run test-licensing",
|
||||
"test": "npm run test-lint && npm run test-unit && npm run test-licensing",
|
||||
"test-lint": "semistandard && cpplint",
|
||||
"test-unit": "nyc --reporter=lcov --branches=99 mocha --slow=1000 --timeout=60000 ./test/unit/*.js",
|
||||
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
|
||||
"test-coverage": "./test/coverage/report.sh",
|
||||
@@ -119,8 +123,8 @@
|
||||
"dependencies": {
|
||||
"color": "^3.1.3",
|
||||
"detect-libc": "^1.0.3",
|
||||
"node-addon-api": "^3.1.0",
|
||||
"prebuild-install": "^6.1.1",
|
||||
"node-addon-api": "^3.2.0",
|
||||
"prebuild-install": "^6.1.2",
|
||||
"semver": "^7.3.5",
|
||||
"simple-get": "^3.1.0",
|
||||
"tar-fs": "^2.1.1",
|
||||
@@ -130,12 +134,12 @@
|
||||
"async": "^3.2.0",
|
||||
"cc": "^3.0.1",
|
||||
"decompress-zip": "^0.3.3",
|
||||
"documentation": "^13.2.0",
|
||||
"documentation": "^13.2.5",
|
||||
"exif-reader": "^1.0.3",
|
||||
"icc": "^2.0.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^8.3.2",
|
||||
"mock-fs": "^4.13.0",
|
||||
"mocha": "^8.4.0",
|
||||
"mock-fs": "^4.14.0",
|
||||
"nyc": "^15.1.0",
|
||||
"prebuild": "^10.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace sharp {
|
||||
descriptor->rawChannels = AttrAsUint32(input, "rawChannels");
|
||||
descriptor->rawWidth = AttrAsUint32(input, "rawWidth");
|
||||
descriptor->rawHeight = AttrAsUint32(input, "rawHeight");
|
||||
descriptor->rawPremultiplied = AttrAsBool(input, "rawPremultiplied");
|
||||
}
|
||||
// Multi-page input (GIF, TIFF, PDF)
|
||||
if (HasAttr(input, "pages")) {
|
||||
@@ -235,6 +236,7 @@ namespace sharp {
|
||||
{ "VipsForeignLoadFits", ImageType::FITS },
|
||||
{ "VipsForeignLoadOpenexr", ImageType::EXR },
|
||||
{ "VipsForeignLoadVips", ImageType::VIPS },
|
||||
{ "VipsForeignLoadVipsFile", ImageType::VIPS },
|
||||
{ "VipsForeignLoadRaw", ImageType::RAW }
|
||||
};
|
||||
|
||||
@@ -301,6 +303,9 @@ namespace sharp {
|
||||
} else {
|
||||
image.get_image()->Type = VIPS_INTERPRETATION_sRGB;
|
||||
}
|
||||
if (descriptor->rawPremultiplied) {
|
||||
image = image.unpremultiply();
|
||||
}
|
||||
imageType = ImageType::RAW;
|
||||
} else {
|
||||
// Compressed data
|
||||
@@ -520,9 +525,8 @@ namespace sharp {
|
||||
VImage SetDensity(VImage image, const double density) {
|
||||
const double pixelsPerMm = density / 25.4;
|
||||
VImage copy = image.copy();
|
||||
copy.set("Xres", pixelsPerMm);
|
||||
copy.set("Yres", pixelsPerMm);
|
||||
copy.set(VIPS_META_RESOLUTION_UNIT, "in");
|
||||
copy.get_image()->Xres = pixelsPerMm;
|
||||
copy.get_image()->Yres = pixelsPerMm;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace sharp {
|
||||
int rawChannels;
|
||||
int rawWidth;
|
||||
int rawHeight;
|
||||
bool rawPremultiplied;
|
||||
int pages;
|
||||
int page;
|
||||
int level;
|
||||
@@ -80,6 +81,7 @@ namespace sharp {
|
||||
rawChannels(0),
|
||||
rawWidth(0),
|
||||
rawHeight(0),
|
||||
rawPremultiplied(false),
|
||||
pages(1),
|
||||
page(0),
|
||||
level(0),
|
||||
|
||||
@@ -92,6 +92,13 @@ namespace sharp {
|
||||
return image;
|
||||
}
|
||||
|
||||
/*
|
||||
* Contrast limiting adapative histogram equalization (CLAHE)
|
||||
*/
|
||||
VImage Clahe(VImage image, int const width, int const height, int const maxSlope) {
|
||||
return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope));
|
||||
}
|
||||
|
||||
/*
|
||||
* Gamma encoding/decoding
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,11 @@ namespace sharp {
|
||||
*/
|
||||
VImage Normalise(VImage image);
|
||||
|
||||
/*
|
||||
* Contrast limiting adapative histogram equalization (CLAHE)
|
||||
*/
|
||||
VImage Clahe(VImage image, int const width, int const height, int const maxSlope);
|
||||
|
||||
/*
|
||||
* Gamma encoding/decoding
|
||||
*/
|
||||
|
||||
@@ -226,7 +226,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
if (
|
||||
xshrink == yshrink && xshrink >= 2 * shrink_on_load_factor &&
|
||||
(inputImageType == sharp::ImageType::JPEG || inputImageType == sharp::ImageType::WEBP) &&
|
||||
baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0
|
||||
baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0 &&
|
||||
image.width() > 3 && image.height() > 3 && baton->input->pages == 1
|
||||
) {
|
||||
if (xshrink >= 8 * shrink_on_load_factor) {
|
||||
xfactor = xfactor / 8;
|
||||
@@ -344,6 +345,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
bool const shouldApplyMedian = baton->medianSize > 0;
|
||||
bool const shouldComposite = !baton->composite.empty();
|
||||
bool const shouldModulate = baton->brightness != 1.0 || baton->saturation != 1.0 || baton->hue != 0.0;
|
||||
bool const shouldApplyClahe = baton->claheWidth != 0 && baton->claheHeight != 0;
|
||||
|
||||
if (shouldComposite && !sharp::HasAlpha(image)) {
|
||||
image = sharp::EnsureAlpha(image, 1);
|
||||
@@ -649,6 +651,11 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
image = sharp::Normalise(image);
|
||||
}
|
||||
|
||||
// Apply contrast limiting adaptive histogram equalization (CLAHE)
|
||||
if (shouldApplyClahe) {
|
||||
image = sharp::Clahe(image, baton->claheWidth, baton->claheHeight, baton->claheMaxSlope);
|
||||
}
|
||||
|
||||
// Apply bitwise boolean operation between images
|
||||
if (baton->boolean != nullptr) {
|
||||
VImage booleanImage;
|
||||
@@ -721,6 +728,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
|
||||
image = sharp::SetExifOrientation(image, baton->withMetadataOrientation);
|
||||
}
|
||||
// Override pixel density
|
||||
if (baton->withMetadataDensity > 0) {
|
||||
image = sharp::SetDensity(image, baton->withMetadataDensity);
|
||||
}
|
||||
// Metadata key/value pairs, e.g. EXIF
|
||||
if (!baton->withMetadataStrs.empty()) {
|
||||
image = image.copy();
|
||||
@@ -1325,6 +1336,9 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->linearB = sharp::AttrAsDouble(options, "linearB");
|
||||
baton->greyscale = sharp::AttrAsBool(options, "greyscale");
|
||||
baton->normalise = sharp::AttrAsBool(options, "normalise");
|
||||
baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
|
||||
baton->claheHeight = sharp::AttrAsUint32(options, "claheHeight");
|
||||
baton->claheMaxSlope = sharp::AttrAsUint32(options, "claheMaxSlope");
|
||||
baton->useExifOrientation = sharp::AttrAsBool(options, "useExifOrientation");
|
||||
baton->angle = sharp::AttrAsInt32(options, "angle");
|
||||
baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle");
|
||||
@@ -1384,6 +1398,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->fileOut = sharp::AttrAsStr(options, "fileOut");
|
||||
baton->withMetadata = sharp::AttrAsBool(options, "withMetadata");
|
||||
baton->withMetadataOrientation = sharp::AttrAsUint32(options, "withMetadataOrientation");
|
||||
baton->withMetadataDensity = sharp::AttrAsDouble(options, "withMetadataDensity");
|
||||
baton->withMetadataIcc = sharp::AttrAsStr(options, "withMetadataIcc");
|
||||
Napi::Object mdStrs = options.Get("withMetadataStrs").As<Napi::Object>();
|
||||
Napi::Array mdStrKeys = mdStrs.GetPropertyNames();
|
||||
|
||||
@@ -109,6 +109,9 @@ struct PipelineBaton {
|
||||
double gammaOut;
|
||||
bool greyscale;
|
||||
bool normalise;
|
||||
int claheWidth;
|
||||
int claheHeight;
|
||||
int claheMaxSlope;
|
||||
bool useExifOrientation;
|
||||
int angle;
|
||||
double rotationAngle;
|
||||
@@ -168,6 +171,7 @@ struct PipelineBaton {
|
||||
std::string err;
|
||||
bool withMetadata;
|
||||
int withMetadataOrientation;
|
||||
double withMetadataDensity;
|
||||
std::string withMetadataIcc;
|
||||
std::unordered_map<std::string, std::string> withMetadataStrs;
|
||||
std::unique_ptr<double[]> convKernel;
|
||||
@@ -233,6 +237,9 @@ struct PipelineBaton {
|
||||
gamma(0.0),
|
||||
greyscale(false),
|
||||
normalise(false),
|
||||
claheWidth(0),
|
||||
claheHeight(0),
|
||||
claheMaxSlope(3),
|
||||
useExifOrientation(false),
|
||||
angle(0),
|
||||
rotationAngle(0.0),
|
||||
@@ -290,6 +297,7 @@ struct PipelineBaton {
|
||||
heifLossless(false),
|
||||
withMetadata(false),
|
||||
withMetadataOrientation(-1),
|
||||
withMetadataDensity(0.0),
|
||||
convKernelWidth(0),
|
||||
convKernelHeight(0),
|
||||
convKernelScale(0.0),
|
||||
|
||||
BIN
test/fixtures/concert.jpg
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
test/fixtures/expected/clahe-100-100-0.jpg
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
test/fixtures/expected/clahe-100-50-3.jpg
vendored
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
test/fixtures/expected/clahe-11-25-14.jpg
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
test/fixtures/expected/clahe-5-5-0.jpg
vendored
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
test/fixtures/expected/clahe-5-5-5.jpg
vendored
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
test/fixtures/expected/clahe-50-50-0.jpg
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
test/fixtures/expected/clahe-50-50-14.jpg
vendored
Normal file
|
After Width: | Height: | Size: 21 KiB |
3
test/fixtures/index.js
vendored
@@ -90,6 +90,7 @@ module.exports = {
|
||||
inputPngEmbed: getPath('embedgravitybird.png'), // Released to sharp under a CC BY 4.0
|
||||
inputPngRGBWithAlpha: getPath('2569067123_aca715a2ee_o.png'), // http://www.flickr.com/photos/grizdave/2569067123/ (same as inputJpg)
|
||||
inputPngImageInAlpha: getPath('image-in-alpha.png'), // https://github.com/lovell/sharp/issues/1597
|
||||
inputPngSolidAlpha: getPath('with-alpha.png'), // https://github.com/lovell/sharp/issues/1599
|
||||
|
||||
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
||||
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
||||
@@ -120,6 +121,8 @@ module.exports = {
|
||||
|
||||
inputV: getPath('vfile.v'),
|
||||
|
||||
inputJpgClahe: getPath('concert.jpg'), // public domain - https://www.flickr.com/photos/mars_/14389236779/
|
||||
|
||||
testPattern: getPath('test-pattern.png'),
|
||||
|
||||
// Path for tests requiring human inspection
|
||||
|
||||
BIN
test/fixtures/with-alpha.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
@@ -19,6 +19,17 @@ describe('HTTP agent', function () {
|
||||
assert.strictEqual(443, proxy.defaultPort);
|
||||
});
|
||||
|
||||
it('HTTPS proxy with auth from HTTPS_PROXY using credentials containing special characters', function () {
|
||||
process.env.HTTPS_PROXY = 'https://user,:pass=@secure:123';
|
||||
const proxy = agent();
|
||||
delete process.env.HTTPS_PROXY;
|
||||
assert.strictEqual('object', typeof proxy);
|
||||
assert.strictEqual('secure', proxy.options.proxy.host);
|
||||
assert.strictEqual(123, proxy.options.proxy.port);
|
||||
assert.strictEqual('user,:pass=', proxy.options.proxy.proxyAuth);
|
||||
assert.strictEqual(443, proxy.defaultPort);
|
||||
});
|
||||
|
||||
it('HTTP proxy without auth from npm_config_proxy', function () {
|
||||
process.env.npm_config_proxy = 'http://plaintext:456';
|
||||
const proxy = agent();
|
||||
|
||||
139
test/unit/clahe.js
Normal file
@@ -0,0 +1,139 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
const sharp = require('../../lib');
|
||||
const fixtures = require('../fixtures');
|
||||
|
||||
describe('Clahe', function () {
|
||||
it('width 5 width 5 maxSlope 0', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 5, height: 5, maxSlope: 0 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-5-5-0.jpg'), data, { threshold: 10 }, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('width 5 width 5 maxSlope 5', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 5, height: 5, maxSlope: 5 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-5-5-5.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('width 11 width 25 maxSlope 14', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 11, height: 25, maxSlope: 14 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-11-25-14.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('width 50 width 50 maxSlope 0', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 50, height: 50, maxSlope: 0 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-50-50-0.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('width 50 width 50 maxSlope 14', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 50, height: 50, maxSlope: 14 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-50-50-14.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('width 100 width 50 maxSlope 3', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 100, height: 50, maxSlope: 3 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-100-50-3.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('width 100 width 100 maxSlope 0', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 100, height: 100, maxSlope: 0 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-100-100-0.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('invalid maxSlope', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: 100, maxSlope: -5 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: 100, maxSlope: 110 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: 100, maxSlope: 5.5 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: 100, maxSlope: 'a string' });
|
||||
});
|
||||
});
|
||||
|
||||
it('invalid width', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100.5, height: 100 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: -5, height: 100 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: true, height: 100 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 'string test', height: 100 });
|
||||
});
|
||||
});
|
||||
|
||||
it('invalid height', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: 100.5 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: -5 });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: true });
|
||||
});
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe({ width: 100, height: 'string test' });
|
||||
});
|
||||
});
|
||||
|
||||
it('invalid options object', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpgClahe).clahe(100, 100, 5);
|
||||
});
|
||||
});
|
||||
|
||||
it('uses default maxSlope of 3', function (done) {
|
||||
sharp(fixtures.inputJpgClahe)
|
||||
.clahe({ width: 100, height: 50 })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
fixtures.assertSimilar(fixtures.expected('clahe-100-50-3.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -335,17 +335,6 @@ describe('Input/output', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail when input is empty Buffer', function (done) {
|
||||
sharp(Buffer.alloc(0)).toBuffer().then(function () {
|
||||
assert(false);
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Input buffer contains unsupported image format', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail when input is invalid Buffer', function (done) {
|
||||
sharp(Buffer.from([0x1, 0x2, 0x3, 0x4])).toBuffer().then(function () {
|
||||
assert(false);
|
||||
|
||||
@@ -240,40 +240,38 @@ describe('Image metadata', function () {
|
||||
})
|
||||
);
|
||||
|
||||
it('GIF via giflib', function (done) {
|
||||
it('GIF', function (done) {
|
||||
sharp(fixtures.inputGif).metadata(function (err, metadata) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('gif', metadata.format);
|
||||
assert.strictEqual('undefined', typeof metadata.size);
|
||||
assert.strictEqual(800, metadata.width);
|
||||
assert.strictEqual(533, metadata.height);
|
||||
assert.strictEqual(3, metadata.channels);
|
||||
assert.strictEqual(true, [3, 4].includes(metadata.channels)); // libvips 8.11.0 = 4
|
||||
assert.strictEqual('uchar', metadata.depth);
|
||||
assert.strictEqual('undefined', typeof 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);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('GIF grey+alpha via giflib', function (done) {
|
||||
it('GIF grey+alpha', function (done) {
|
||||
sharp(fixtures.inputGifGreyPlusAlpha).metadata(function (err, metadata) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('gif', metadata.format);
|
||||
assert.strictEqual('undefined', typeof metadata.size);
|
||||
assert.strictEqual(2, metadata.width);
|
||||
assert.strictEqual(1, metadata.height);
|
||||
assert.strictEqual(2, metadata.channels);
|
||||
assert.strictEqual(true, [2, 4].includes(metadata.channels)); // libvips 8.11.0 = 4
|
||||
assert.strictEqual('uchar', metadata.depth);
|
||||
assert.strictEqual('undefined', typeof metadata.density);
|
||||
assert.strictEqual('undefined', typeof metadata.chromaSubsampling);
|
||||
assert.strictEqual(false, metadata.isProgressive);
|
||||
assert.strictEqual(false, metadata.hasProfile);
|
||||
assert.strictEqual(true, metadata.hasAlpha);
|
||||
assert.strictEqual('undefined', typeof metadata.orientation);
|
||||
assert.strictEqual('undefined', typeof metadata.exif);
|
||||
assert.strictEqual('undefined', typeof metadata.icc);
|
||||
@@ -322,7 +320,7 @@ describe('Image metadata', function () {
|
||||
assert.strictEqual(isProgressive, false);
|
||||
assert.strictEqual(pages, 10);
|
||||
assert.strictEqual(pageHeight, 285);
|
||||
assert.strictEqual(loop, 3);
|
||||
assert.strictEqual(true, [2, 3].includes(loop)); // libvips 8.11.0 = 2
|
||||
assert.deepStrictEqual(delay, [...Array(9).fill(3000), 15000]);
|
||||
assert.strictEqual(hasProfile, false);
|
||||
assert.strictEqual(hasAlpha, true);
|
||||
@@ -623,6 +621,44 @@ describe('Image metadata', function () {
|
||||
assert.strictEqual(parsedExif.exif.ExposureTime, 0.2);
|
||||
});
|
||||
|
||||
it('Set density of JPEG', async () => {
|
||||
const data = await sharp({
|
||||
create: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 3,
|
||||
background: 'red'
|
||||
}
|
||||
})
|
||||
.withMetadata({
|
||||
density: 300
|
||||
})
|
||||
.jpeg()
|
||||
.toBuffer();
|
||||
|
||||
const { density } = await sharp(data).metadata();
|
||||
assert.strictEqual(density, 300);
|
||||
});
|
||||
|
||||
it('Set density of PNG', async () => {
|
||||
const data = await sharp({
|
||||
create: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 3,
|
||||
background: 'red'
|
||||
}
|
||||
})
|
||||
.withMetadata({
|
||||
density: 96
|
||||
})
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
const { density } = await sharp(data).metadata();
|
||||
assert.strictEqual(density, 96);
|
||||
});
|
||||
|
||||
it('chromaSubsampling 4:4:4:4 CMYK JPEG', function () {
|
||||
return sharp(fixtures.inputJpgWithCmykProfile)
|
||||
.metadata()
|
||||
@@ -736,6 +772,16 @@ describe('Image metadata', function () {
|
||||
sharp().withMetadata({ orientation: 9 });
|
||||
});
|
||||
});
|
||||
it('Non-numeric density', function () {
|
||||
assert.throws(function () {
|
||||
sharp().withMetadata({ density: '1' });
|
||||
});
|
||||
});
|
||||
it('Negative density', function () {
|
||||
assert.throws(function () {
|
||||
sharp().withMetadata({ density: -1 });
|
||||
});
|
||||
});
|
||||
it('Non string icc', function () {
|
||||
assert.throws(function () {
|
||||
sharp().withMetadata({ icc: true });
|
||||
|
||||
@@ -32,23 +32,21 @@ describe('Platform-detection', function () {
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
|
||||
it('Can detect ARM version via process.config', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
const armVersion = process.config.variables.arm_version;
|
||||
process.config.variables.arm_version = 'test';
|
||||
assert.strictEqual('armvtest', platform().split('-')[1]);
|
||||
process.config.variables.arm_version = armVersion;
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
if (process.config.variables.arm_version) {
|
||||
it('Can detect ARM version via process.config', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
assert.strictEqual(`armv${process.config.variables.arm_version}`, platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
}
|
||||
|
||||
it('Defaults to ARMv6 for 32-bit', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
const armVersion = process.config.variables.arm_version;
|
||||
delete process.config.variables.arm_version;
|
||||
assert.strictEqual('armv6', platform().split('-')[1]);
|
||||
process.config.variables.arm_version = armVersion;
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
if (!process.config.variables.arm_version) {
|
||||
it('Defaults to ARMv6 for 32-bit', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
assert.strictEqual('armv6', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
}
|
||||
|
||||
it('Defaults to ARMv8 for 64-bit', function () {
|
||||
process.env.npm_config_arch = 'arm64';
|
||||
|
||||
@@ -7,6 +7,18 @@ const fixtures = require('../fixtures');
|
||||
|
||||
describe('Raw pixel data', function () {
|
||||
describe('Raw pixel input', function () {
|
||||
it('Empty data', function () {
|
||||
assert.throws(function () {
|
||||
sharp(Buffer.from(''));
|
||||
}, /empty/);
|
||||
assert.throws(function () {
|
||||
sharp(new Uint8Array(0));
|
||||
}, /empty/);
|
||||
assert.throws(function () {
|
||||
sharp(new Uint8ClampedArray(0));
|
||||
}, /empty/);
|
||||
});
|
||||
|
||||
it('Missing options', function () {
|
||||
assert.throws(function () {
|
||||
sharp({ raw: {} });
|
||||
@@ -95,6 +107,52 @@ describe('Raw pixel data', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('RGBA premultiplied', function (done) {
|
||||
// Convert to raw pixel data
|
||||
sharp(fixtures.inputPngSolidAlpha)
|
||||
.resize(256)
|
||||
.raw()
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(256, info.width);
|
||||
assert.strictEqual(192, info.height);
|
||||
assert.strictEqual(4, info.channels);
|
||||
|
||||
const originalData = Buffer.from(data);
|
||||
|
||||
// Premultiply image data
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
const alpha = data[i + 3];
|
||||
const norm = alpha / 255;
|
||||
|
||||
if (alpha < 255) {
|
||||
data[i] = Math.round(data[i] * norm);
|
||||
data[i + 1] = Math.round(data[i + 1] * norm);
|
||||
data[i + 2] = Math.round(data[i + 2] * norm);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert back to PNG
|
||||
sharp(data, {
|
||||
raw: {
|
||||
width: info.width,
|
||||
height: info.height,
|
||||
channels: info.channels,
|
||||
premultiplied: true
|
||||
}
|
||||
})
|
||||
.raw()
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(256, info.width);
|
||||
assert.strictEqual(192, info.height);
|
||||
assert.strictEqual(4, info.channels);
|
||||
assert.equal(data.compare(originalData), 0, 'output buffer matches unpremultiplied input buffer');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('JPEG to raw Stream and back again', function (done) {
|
||||
const width = 32;
|
||||
const height = 24;
|
||||
|
||||
@@ -605,6 +605,26 @@ describe('Resize dimensions', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('Skip shrink-on-load where one dimension <4px', async () => {
|
||||
const jpeg = await sharp({
|
||||
create: {
|
||||
width: 100,
|
||||
height: 3,
|
||||
channels: 3,
|
||||
background: 'red'
|
||||
}
|
||||
})
|
||||
.jpeg()
|
||||
.toBuffer();
|
||||
|
||||
const { info } = await sharp(jpeg)
|
||||
.resize(8)
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
|
||||
assert.strictEqual(info.width, 8);
|
||||
assert.strictEqual(info.height, 1);
|
||||
});
|
||||
|
||||
it('unknown kernel throws', function () {
|
||||
assert.throws(function () {
|
||||
sharp().resize(null, null, { kernel: 'unknown' });
|
||||
|
||||