mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 21:56:18 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db654de385 | ||
|
|
a6aeef612b | ||
|
|
7bf6cbd669 | ||
|
|
04c31b35a7 | ||
|
|
ee9cdb6598 | ||
|
|
8960eb8309 | ||
|
|
54d9dc46f5 | ||
|
|
51b4a7c564 | ||
|
|
5b03579e5c | ||
|
|
58c2af3251 | ||
|
|
ee948ac6fa | ||
|
|
66a3ce5e55 | ||
|
|
75e5afcd42 |
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -16,7 +16,7 @@ If a [similar request](https://github.com/lovell/sharp/labels/enhancement) exist
|
|||||||
it's probably fastest to add a comment to it about your requirement.
|
it's probably fastest to add a comment to it about your requirement.
|
||||||
|
|
||||||
Implementation is usually straightforward if libvips
|
Implementation is usually straightforward if libvips
|
||||||
[already supports](https://libvips.github.io/libvips/API/current/func-list.html)
|
[already supports](https://www.libvips.org/API/current/func-list.html)
|
||||||
the feature you need.
|
the feature you need.
|
||||||
|
|
||||||
## Submit a Pull Request to fix a bug
|
## Submit a Pull Request to fix a bug
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
|
|||||||
`hard-light`, `soft-light`, `difference`, `exclusion`.
|
`hard-light`, `soft-light`, `difference`, `exclusion`.
|
||||||
|
|
||||||
More information about blend modes can be found at
|
More information about blend modes can be found at
|
||||||
[https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode][1]
|
[https://www.libvips.org/API/current/libvips-conversion.html#VipsBlendMode][1]
|
||||||
and [https://www.cairographics.org/operators/][2]
|
and [https://www.cairographics.org/operators/][2]
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
@@ -89,7 +89,7 @@ Returns **Sharp**
|
|||||||
|
|
||||||
* **since**: 0.22.0
|
* **since**: 0.22.0
|
||||||
|
|
||||||
[1]: https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
|
[1]: https://www.libvips.org/API/current/libvips-conversion.html#VipsBlendMode
|
||||||
|
|
||||||
[2]: https://www.cairographics.org/operators/
|
[2]: https://www.cairographics.org/operators/
|
||||||
|
|
||||||
|
|||||||
@@ -131,9 +131,9 @@ const stats = await sharp(part).stats();
|
|||||||
|
|
||||||
Returns **[Promise][5]<[Object][6]>**
|
Returns **[Promise][5]<[Object][6]>**
|
||||||
|
|
||||||
[1]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation
|
[1]: https://www.libvips.org/API/current/VipsImage.html#VipsInterpretation
|
||||||
|
|
||||||
[2]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat
|
[2]: https://www.libvips.org/API/current/VipsImage.html#VipsBandFormat
|
||||||
|
|
||||||
[3]: https://www.npmjs.com/package/icc
|
[3]: https://www.npmjs.com/package/icc
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ Returns **[Promise][5]<[Object][6]>** when no callback is provided
|
|||||||
Write output to a Buffer.
|
Write output to a Buffer.
|
||||||
JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
||||||
|
|
||||||
|
Use [toFormat][7] or one of the format-specific functions such as [jpeg][8], [png][9] etc. to set the output format.
|
||||||
|
|
||||||
If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
||||||
|
|
||||||
By default all metadata will be removed, which includes EXIF-based orientation.
|
By default all metadata will be removed, which includes EXIF-based orientation.
|
||||||
@@ -66,7 +68,7 @@ A `Promise` is returned when `callback` is not provided.
|
|||||||
|
|
||||||
* `options` **[Object][6]?**
|
* `options` **[Object][6]?**
|
||||||
|
|
||||||
* `options.resolveWithObject` **[boolean][7]?** Resolve the Promise with an Object containing `data` and `info` properties instead of resolving only with `data`.
|
* `options.resolveWithObject` **[boolean][10]?** Resolve the Promise with an Object containing `data` and `info` properties instead of resolving only with `data`.
|
||||||
* `callback` **[Function][3]?**
|
* `callback` **[Function][3]?**
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@@ -85,6 +87,7 @@ sharp(input)
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
sharp(input)
|
sharp(input)
|
||||||
|
.png()
|
||||||
.toBuffer({ resolveWithObject: true })
|
.toBuffer({ resolveWithObject: true })
|
||||||
.then(({ data, info }) => { ... })
|
.then(({ data, info }) => { ... })
|
||||||
.catch(err => { ... });
|
.catch(err => { ... });
|
||||||
@@ -107,7 +110,7 @@ await sharp(pixelArray, { raw: { width, height, channels } })
|
|||||||
.toFile('my-changed-image.jpg');
|
.toFile('my-changed-image.jpg');
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns **[Promise][5]<[Buffer][8]>** when no callback is provided
|
Returns **[Promise][5]<[Buffer][11]>** when no callback is provided
|
||||||
|
|
||||||
## withMetadata
|
## withMetadata
|
||||||
|
|
||||||
@@ -124,10 +127,10 @@ EXIF metadata is unsupported for TIFF output.
|
|||||||
|
|
||||||
* `options` **[Object][6]?**
|
* `options` **[Object][6]?**
|
||||||
|
|
||||||
* `options.orientation` **[number][9]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
|
* `options.orientation` **[number][12]?** 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.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.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).
|
* `options.density` **[number][12]?** Number of pixels per inch (DPI).
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -192,19 +195,19 @@ Use these JPEG options for output image.
|
|||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `80`)
|
* `options.quality` **[number][12]** quality, integer 1-100 (optional, default `80`)
|
||||||
* `options.progressive` **[boolean][7]** use progressive (interlace) scan (optional, default `false`)
|
* `options.progressive` **[boolean][10]** 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.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.optimiseCoding` **[boolean][10]** optimise Huffman coding tables (optional, default `true`)
|
||||||
* `options.optimizeCoding` **[boolean][7]** alternative spelling of optimiseCoding (optional, default `true`)
|
* `options.optimizeCoding` **[boolean][10]** 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.mozjpeg` **[boolean][10]** 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.trellisQuantisation` **[boolean][10]** apply trellis quantisation (optional, default `false`)
|
||||||
* `options.overshootDeringing` **[boolean][7]** apply overshoot deringing (optional, default `false`)
|
* `options.overshootDeringing` **[boolean][10]** apply overshoot deringing (optional, default `false`)
|
||||||
* `options.optimiseScans` **[boolean][7]** optimise progressive scans, forces progressive (optional, default `false`)
|
* `options.optimiseScans` **[boolean][10]** optimise progressive scans, forces progressive (optional, default `false`)
|
||||||
* `options.optimizeScans` **[boolean][7]** alternative spelling of optimiseScans (optional, default `false`)
|
* `options.optimizeScans` **[boolean][10]** alternative spelling of optimiseScans (optional, default `false`)
|
||||||
* `options.quantisationTable` **[number][9]** quantization table to use, integer 0-8 (optional, default `0`)
|
* `options.quantisationTable` **[number][12]** quantization table to use, integer 0-8 (optional, default `0`)
|
||||||
* `options.quantizationTable` **[number][9]** alternative spelling of quantisationTable (optional, default `0`)
|
* `options.quantizationTable` **[number][12]** alternative spelling of quantisationTable (optional, default `0`)
|
||||||
* `options.force` **[boolean][7]** force JPEG output, otherwise attempt to use input format (optional, default `true`)
|
* `options.force` **[boolean][10]** force JPEG output, otherwise attempt to use input format (optional, default `true`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -241,16 +244,16 @@ Set `palette` to `true` for slower, indexed PNG output.
|
|||||||
|
|
||||||
* `options` **[Object][6]?**
|
* `options` **[Object][6]?**
|
||||||
|
|
||||||
* `options.progressive` **[boolean][7]** use progressive (interlace) scan (optional, default `false`)
|
* `options.progressive` **[boolean][10]** 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.compressionLevel` **[number][12]** 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.adaptiveFiltering` **[boolean][10]** 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.palette` **[boolean][10]** 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.quality` **[number][12]** use the lowest number of colours needed to achieve given quality, sets `palette` to `true` (optional, default `100`)
|
||||||
* `options.effort` **[number][9]** CPU effort, between 1 (fastest) and 10 (slowest), sets `palette` to `true` (optional, default `7`)
|
* `options.effort` **[number][12]** CPU effort, between 1 (fastest) and 10 (slowest), sets `palette` to `true` (optional, default `7`)
|
||||||
* `options.colours` **[number][9]** maximum number of palette entries, sets `palette` to `true` (optional, default `256`)
|
* `options.colours` **[number][12]** 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.colors` **[number][12]** 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.dither` **[number][12]** 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.force` **[boolean][10]** force PNG output, otherwise attempt to use input format (optional, default `true`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -280,15 +283,15 @@ Use these WebP options for output image.
|
|||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `80`)
|
* `options.quality` **[number][12]** quality, integer 1-100 (optional, default `80`)
|
||||||
* `options.alphaQuality` **[number][9]** quality of alpha layer, integer 0-100 (optional, default `100`)
|
* `options.alphaQuality` **[number][12]** quality of alpha layer, integer 0-100 (optional, default `100`)
|
||||||
* `options.lossless` **[boolean][7]** use lossless compression mode (optional, default `false`)
|
* `options.lossless` **[boolean][10]** use lossless compression mode (optional, default `false`)
|
||||||
* `options.nearLossless` **[boolean][7]** use near_lossless compression mode (optional, default `false`)
|
* `options.nearLossless` **[boolean][10]** use near_lossless compression mode (optional, default `false`)
|
||||||
* `options.smartSubsample` **[boolean][7]** use high quality chroma subsampling (optional, default `false`)
|
* `options.smartSubsample` **[boolean][10]** use high quality chroma subsampling (optional, default `false`)
|
||||||
* `options.effort` **[number][9]** CPU effort, between 0 (fastest) and 6 (slowest) (optional, default `4`)
|
* `options.effort` **[number][12]** CPU effort, between 0 (fastest) and 6 (slowest) (optional, default `4`)
|
||||||
* `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
* `options.loop` **[number][12]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
||||||
* `options.delay` **([number][9] | [Array][10]<[number][9]>)?** delay(s) between animation frames (in milliseconds)
|
* `options.delay` **([number][12] | [Array][13]<[number][12]>)?** delay(s) between animation frames (in milliseconds)
|
||||||
* `options.force` **[boolean][7]** force WebP output, otherwise attempt to use input format (optional, default `true`)
|
* `options.force` **[boolean][10]** force WebP output, otherwise attempt to use input format (optional, default `true`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -320,13 +323,13 @@ The first entry in the palette is reserved for transparency.
|
|||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.colours` **[number][9]** maximum number of palette entries, including transparency, between 2 and 256 (optional, default `256`)
|
* `options.colours` **[number][12]** maximum number of palette entries, including transparency, between 2 and 256 (optional, default `256`)
|
||||||
* `options.colors` **[number][9]** alternative spelling of `options.colours` (optional, default `256`)
|
* `options.colors` **[number][12]** alternative spelling of `options.colours` (optional, default `256`)
|
||||||
* `options.effort` **[number][9]** CPU effort, between 1 (fastest) and 10 (slowest) (optional, default `7`)
|
* `options.effort` **[number][12]** CPU effort, between 1 (fastest) and 10 (slowest) (optional, default `7`)
|
||||||
* `options.dither` **[number][9]** level of Floyd-Steinberg error diffusion, between 0 (least) and 1 (most) (optional, default `1.0`)
|
* `options.dither` **[number][12]** level of Floyd-Steinberg error diffusion, between 0 (least) and 1 (most) (optional, default `1.0`)
|
||||||
* `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
* `options.loop` **[number][12]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
|
||||||
* `options.delay` **([number][9] | [Array][10]<[number][9]>)?** delay(s) between animation frames (in milliseconds)
|
* `options.delay` **([number][12] | [Array][13]<[number][12]>)?** delay(s) between animation frames (in milliseconds)
|
||||||
* `options.force` **[boolean][7]** force GIF output, otherwise attempt to use input format (optional, default `true`)
|
* `options.force` **[boolean][10]** force GIF output, otherwise attempt to use input format (optional, default `true`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -334,7 +337,7 @@ The first entry in the palette is reserved for transparency.
|
|||||||
// Convert PNG to GIF
|
// Convert PNG to GIF
|
||||||
await sharp(pngBuffer)
|
await sharp(pngBuffer)
|
||||||
.gif()
|
.gif()
|
||||||
.toBuffer());
|
.toBuffer();
|
||||||
```
|
```
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -365,16 +368,16 @@ Use these JP2 options for output image.
|
|||||||
|
|
||||||
Requires libvips compiled with support for OpenJPEG.
|
Requires libvips compiled with support for OpenJPEG.
|
||||||
The prebuilt binaries do not include this - see
|
The prebuilt binaries do not include this - see
|
||||||
[installing a custom libvips][11].
|
[installing a custom libvips][14].
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `80`)
|
* `options.quality` **[number][12]** quality, integer 1-100 (optional, default `80`)
|
||||||
* `options.lossless` **[boolean][7]** use lossless compression mode (optional, default `false`)
|
* `options.lossless` **[boolean][10]** use lossless compression mode (optional, default `false`)
|
||||||
* `options.tileWidth` **[number][9]** horizontal tile size (optional, default `512`)
|
* `options.tileWidth` **[number][12]** horizontal tile size (optional, default `512`)
|
||||||
* `options.tileHeight` **[number][9]** vertical tile size (optional, default `512`)
|
* `options.tileHeight` **[number][12]** vertical tile size (optional, default `512`)
|
||||||
* `options.chromaSubsampling` **[string][2]** set to '4:2:0' to use chroma subsampling (optional, default `'4:4:4'`)
|
* `options.chromaSubsampling` **[string][2]** set to '4:2:0' to use chroma subsampling (optional, default `'4:4:4'`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@@ -414,18 +417,18 @@ The `density` can be set in pixels/inch via [withMetadata][1] instead of providi
|
|||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `80`)
|
* `options.quality` **[number][12]** quality, integer 1-100 (optional, default `80`)
|
||||||
* `options.force` **[boolean][7]** force TIFF output, otherwise attempt to use input format (optional, default `true`)
|
* `options.force` **[boolean][10]** 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.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.predictor` **[string][2]** compression predictor options: none, horizontal, float (optional, default `'horizontal'`)
|
||||||
* `options.pyramid` **[boolean][7]** write an image pyramid (optional, default `false`)
|
* `options.pyramid` **[boolean][10]** write an image pyramid (optional, default `false`)
|
||||||
* `options.tile` **[boolean][7]** write a tiled tiff (optional, default `false`)
|
* `options.tile` **[boolean][10]** write a tiled tiff (optional, default `false`)
|
||||||
* `options.tileWidth` **[number][9]** horizontal tile size (optional, default `256`)
|
* `options.tileWidth` **[number][12]** horizontal tile size (optional, default `256`)
|
||||||
* `options.tileHeight` **[number][9]** vertical tile size (optional, default `256`)
|
* `options.tileHeight` **[number][12]** vertical tile size (optional, default `256`)
|
||||||
* `options.xres` **[number][9]** horizontal resolution in pixels/mm (optional, default `1.0`)
|
* `options.xres` **[number][12]** horizontal resolution in pixels/mm (optional, default `1.0`)
|
||||||
* `options.yres` **[number][9]** vertical resolution in pixels/mm (optional, default `1.0`)
|
* `options.yres` **[number][12]** vertical resolution in pixels/mm (optional, default `1.0`)
|
||||||
* `options.resolutionUnit` **[string][2]** resolution unit options: inch, cm (optional, default `'inch'`)
|
* `options.resolutionUnit` **[string][2]** resolution unit options: inch, cm (optional, default `'inch'`)
|
||||||
* `options.bitdepth` **[number][9]** reduce bitdepth to 1, 2 or 4 bit (optional, default `8`)
|
* `options.bitdepth` **[number][12]** reduce bitdepth to 1, 2 or 4 bit (optional, default `8`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -457,9 +460,9 @@ AVIF image sequences are not supported.
|
|||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `50`)
|
* `options.quality` **[number][12]** quality, integer 1-100 (optional, default `50`)
|
||||||
* `options.lossless` **[boolean][7]** use lossless compression (optional, default `false`)
|
* `options.lossless` **[boolean][10]** use lossless compression (optional, default `false`)
|
||||||
* `options.effort` **[number][9]** CPU effort, between 0 (fastest) and 9 (slowest) (optional, default `4`)
|
* `options.effort` **[number][12]** CPU effort, between 0 (fastest) and 9 (slowest) (optional, default `4`)
|
||||||
* `options.chromaSubsampling` **[string][2]** set to '4:2:0' to use chroma subsampling (optional, default `'4:4:4'`)
|
* `options.chromaSubsampling` **[string][2]** set to '4:2:0' to use chroma subsampling (optional, default `'4:4:4'`)
|
||||||
|
|
||||||
<!---->
|
<!---->
|
||||||
@@ -483,10 +486,10 @@ globally-installed libvips compiled with support for libheif, libde265 and x265.
|
|||||||
|
|
||||||
* `options` **[Object][6]?** output options
|
* `options` **[Object][6]?** output options
|
||||||
|
|
||||||
* `options.quality` **[number][9]** quality, integer 1-100 (optional, default `50`)
|
* `options.quality` **[number][12]** quality, integer 1-100 (optional, default `50`)
|
||||||
* `options.compression` **[string][2]** compression format: av1, hevc (optional, default `'av1'`)
|
* `options.compression` **[string][2]** compression format: av1, hevc (optional, default `'av1'`)
|
||||||
* `options.lossless` **[boolean][7]** use lossless compression (optional, default `false`)
|
* `options.lossless` **[boolean][10]** use lossless compression (optional, default `false`)
|
||||||
* `options.effort` **[number][9]** CPU effort, between 0 (fastest) and 9 (slowest) (optional, default `4`)
|
* `options.effort` **[number][12]** CPU effort, between 0 (fastest) and 9 (slowest) (optional, default `4`)
|
||||||
* `options.chromaSubsampling` **[string][2]** set to '4:2:0' to use chroma subsampling (optional, default `'4:4:4'`)
|
* `options.chromaSubsampling` **[string][2]** set to '4:2:0' to use chroma subsampling (optional, default `'4:4:4'`)
|
||||||
|
|
||||||
<!---->
|
<!---->
|
||||||
@@ -542,16 +545,16 @@ Use a `.zip` or `.szi` file extension with `toFile` to write to a compressed arc
|
|||||||
|
|
||||||
* `options` **[Object][6]?**
|
* `options` **[Object][6]?**
|
||||||
|
|
||||||
* `options.size` **[number][9]** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
|
* `options.size` **[number][12]** 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.overlap` **[number][12]** 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.angle` **[number][12]** 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.background` **([string][2] | [Object][6])** background colour, parsed by the [color][15] 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.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.skipBlanks` **[number][12]** 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.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`, `iiif3`, `zoomify` or `google`. (optional, default `'dz'`)
|
* `options.layout` **[string][2]** filesystem layout, possible values are `dz`, `iiif`, `iiif3`, `zoomify` or `google`. (optional, default `'dz'`)
|
||||||
* `options.centre` **[boolean][7]** centre image in tile. (optional, default `false`)
|
* `options.centre` **[boolean][10]** centre image in tile. (optional, default `false`)
|
||||||
* `options.center` **[boolean][7]** alternative spelling of centre. (optional, default `false`)
|
* `options.center` **[boolean][10]** alternative spelling of centre. (optional, default `false`)
|
||||||
* `options.id` **[string][2]** when `layout` is `iiif`/`iiif3`, sets the `@id`/`id` attribute of `info.json` (optional, default `'https://example.com/iiif'`)
|
* `options.id` **[string][2]** when `layout` is `iiif`/`iiif3`, sets the `@id`/`id` attribute of `info.json` (optional, default `'https://example.com/iiif'`)
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@@ -584,7 +587,7 @@ Time spent waiting for a libuv thread to become available is not included.
|
|||||||
|
|
||||||
* `options` **[Object][6]**
|
* `options` **[Object][6]**
|
||||||
|
|
||||||
* `options.seconds` **[number][9]** Number of seconds after which processing will be stopped
|
* `options.seconds` **[number][12]** Number of seconds after which processing will be stopped
|
||||||
|
|
||||||
Returns **Sharp**
|
Returns **Sharp**
|
||||||
|
|
||||||
@@ -604,14 +607,20 @@ Returns **Sharp**
|
|||||||
|
|
||||||
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||||
|
|
||||||
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
[7]: #toformat
|
||||||
|
|
||||||
[8]: https://nodejs.org/api/buffer.html
|
[8]: #jpeg
|
||||||
|
|
||||||
[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
[9]: #png
|
||||||
|
|
||||||
[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
||||||
|
|
||||||
[11]: https://sharp.pixelplumbing.com/install#custom-libvips
|
[11]: https://nodejs.org/api/buffer.html
|
||||||
|
|
||||||
[12]: https://www.npmjs.org/package/color
|
[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
||||||
|
|
||||||
|
[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
||||||
|
|
||||||
|
[14]: https://sharp.pixelplumbing.com/install#custom-libvips
|
||||||
|
|
||||||
|
[15]: https://www.npmjs.org/package/color
|
||||||
|
|||||||
@@ -95,7 +95,11 @@ Returns **[Object][1]**
|
|||||||
## concurrency
|
## concurrency
|
||||||
|
|
||||||
Gets or, when a concurrency is provided, sets
|
Gets or, when a concurrency is provided, sets
|
||||||
the number of threads *libvips'* should create to process each image.
|
the maximum number of threads *libvips* should use to process *each image*.
|
||||||
|
These are from a thread pool managed by glib,
|
||||||
|
which helps avoid the overhead of creating new threads.
|
||||||
|
|
||||||
|
This method always returns the current concurrency.
|
||||||
|
|
||||||
The default value is the number of CPU cores,
|
The default value is the number of CPU cores,
|
||||||
except when using glibc-based Linux without jemalloc,
|
except when using glibc-based Linux without jemalloc,
|
||||||
@@ -103,10 +107,19 @@ where the default is `1` to help reduce memory fragmentation.
|
|||||||
|
|
||||||
A value of `0` will reset this to the number of CPU cores.
|
A value of `0` will reset this to the number of CPU cores.
|
||||||
|
|
||||||
The maximum number of images that can be processed in parallel
|
Some image format libraries spawn additional threads,
|
||||||
is limited by libuv's `UV_THREADPOOL_SIZE` environment variable.
|
e.g. libaom manages its own 4 threads when encoding AVIF images,
|
||||||
|
and these are independent of the value set here.
|
||||||
|
|
||||||
This method always returns the current concurrency.
|
The maximum number of images that sharp can process in parallel
|
||||||
|
is controlled by libuv's `UV_THREADPOOL_SIZE` environment variable,
|
||||||
|
which defaults to 4.
|
||||||
|
|
||||||
|
[https://nodejs.org/api/cli.html#uv_threadpool_sizesize][12]
|
||||||
|
|
||||||
|
For example, by default, a machine with 8 CPU cores will process
|
||||||
|
4 images in parallel and use up to 8 threads per image,
|
||||||
|
so there will be up to 32 concurrent threads.
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
@@ -199,3 +212,5 @@ Returns **[boolean][10]**
|
|||||||
[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
||||||
|
|
||||||
[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
||||||
|
|
||||||
|
[12]: https://nodejs.org/api/cli.html#uv_threadpool_sizesize
|
||||||
|
|||||||
@@ -4,6 +4,19 @@
|
|||||||
|
|
||||||
Requires libvips v8.12.2
|
Requires libvips v8.12.2
|
||||||
|
|
||||||
|
### v0.30.5 - 23rd May 2022
|
||||||
|
|
||||||
|
* Install: pass `PKG_CONFIG_PATH` via env rather than substitution.
|
||||||
|
[@dwisiswant0](https://github.com/dwisiswant0)
|
||||||
|
|
||||||
|
* Allow installation of prebuilt libvips binaries from filesystem.
|
||||||
|
[#3196](https://github.com/lovell/sharp/pull/3196)
|
||||||
|
[@ankurparihar](https://github.com/ankurparihar)
|
||||||
|
|
||||||
|
* Fix rotate-then-extract for EXIF orientation 2.
|
||||||
|
[#3218](https://github.com/lovell/sharp/pull/3218)
|
||||||
|
[@jakob0fischl](https://github.com/jakob0fischl)
|
||||||
|
|
||||||
### v0.30.4 - 18th April 2022
|
### v0.30.4 - 18th April 2022
|
||||||
|
|
||||||
* Increase control over sensitivity to invalid images via `failOn`, deprecate `failOnError` (equivalent to `failOn: 'warning'`).
|
* Increase control over sensitivity to invalid images via `failOn`, deprecate `failOnError` (equivalent to `failOn: 'warning'`).
|
||||||
|
|||||||
@@ -242,3 +242,6 @@ GitHub: https://github.com/codepage949
|
|||||||
|
|
||||||
Name: Chris Hranj
|
Name: Chris Hranj
|
||||||
GitHub: https://github.com/Brodan
|
GitHub: https://github.com/Brodan
|
||||||
|
|
||||||
|
Name: Ankur Parihar
|
||||||
|
GitHub: https://github.com/ankurparihar
|
||||||
|
|||||||
@@ -74,20 +74,28 @@ The target platform and/or architecture can be manually selected using the follo
|
|||||||
npm install --platform=... --arch=... --arm-version=... sharp
|
npm install --platform=... --arch=... --arm-version=... sharp
|
||||||
```
|
```
|
||||||
|
|
||||||
* `--platform`: one of `linux`, `linuxmusl`, `darwin` or `win32`.
|
* `--platform`: one of `linux`, `darwin` or `win32`.
|
||||||
* `--arch`: one of `x64`, `ia32`, `arm` or `arm64`.
|
* `--arch`: one of `x64`, `ia32`, `arm` or `arm64`.
|
||||||
* `--arm-version`: one of `6`, `7` or `8` (`arm` defaults to `6`, `arm64` defaults to `8`).
|
* `--arm-version`: one of `6`, `7` or `8` (`arm` defaults to `6`, `arm64` defaults to `8`).
|
||||||
|
* `--libc`: one of `glibc` or `musl`. This option only works with platform `linux`, defaults to `glibc`
|
||||||
* `--sharp-install-force`: skip version compatibility and Subresource Integrity checks.
|
* `--sharp-install-force`: skip version compatibility and Subresource Integrity checks.
|
||||||
|
|
||||||
These values can also be set via environment variables,
|
These values can also be set via environment variables,
|
||||||
`npm_config_platform`, `npm_config_arch`, `npm_config_arm_version`
|
`npm_config_platform`, `npm_config_arch`, `npm_config_arm_version`, `npm_config_libc`
|
||||||
and `SHARP_INSTALL_FORCE` respectively.
|
and `SHARP_INSTALL_FORCE` respectively.
|
||||||
|
|
||||||
For example, if the target machine has a 64-bit ARM CPU and is running Alpine Linux,
|
For example, if the target machine has a 64-bit ARM CPU and is running Alpine Linux,
|
||||||
use the following flags:
|
use the following flags:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install --arch=arm64 --platform=linuxmusl sharp
|
npm install --arch=arm64 --platform=linux --libc=musl sharp
|
||||||
|
```
|
||||||
|
|
||||||
|
If the current machine is Alpine Linux and the target machine is Debian Linux on x64 cpu,
|
||||||
|
use the following flags:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --arch=x64 --platform=linux --libc=glibc sharp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Custom libvips
|
## Custom libvips
|
||||||
@@ -96,8 +104,8 @@ To use a custom, globally-installed version of libvips instead of the provided b
|
|||||||
make sure it is at least the version listed under `config.libvips` in the `package.json` file
|
make sure it is at least the version listed under `config.libvips` in the `package.json` file
|
||||||
and that it can be located using `pkg-config --modversion vips-cpp`.
|
and that it can be located using `pkg-config --modversion vips-cpp`.
|
||||||
|
|
||||||
For help compiling libvips from source, please see
|
For help compiling libvips and its dependencies, please see
|
||||||
[https://libvips.github.io/libvips/install.html#building-libvips-from-a-source-tarball](https://libvips.github.io/libvips/install.html#building-libvips-from-a-source-tarball).
|
[building libvips from source](https://www.libvips.org/install.html#building-libvips-from-source).
|
||||||
|
|
||||||
The use of a globally-installed libvips is unsupported on Windows.
|
The use of a globally-installed libvips is unsupported on Windows.
|
||||||
|
|
||||||
@@ -118,6 +126,8 @@ Building from source requires:
|
|||||||
|
|
||||||
This is an advanced approach that most people will not require.
|
This is an advanced approach that most people will not require.
|
||||||
|
|
||||||
|
### Prebuilt sharp binaries
|
||||||
|
|
||||||
To install the prebuilt sharp binaries from a custom URL,
|
To install the prebuilt sharp binaries from a custom URL,
|
||||||
set the `sharp_binary_host` npm config option
|
set the `sharp_binary_host` npm config option
|
||||||
or the `npm_config_sharp_binary_host` environment variable.
|
or the `npm_config_sharp_binary_host` environment variable.
|
||||||
@@ -126,10 +136,16 @@ To install the prebuilt sharp binaries from a directory on the local filesystem,
|
|||||||
set the `sharp_local_prebuilds` npm config option
|
set the `sharp_local_prebuilds` npm config option
|
||||||
or the `npm_config_sharp_local_prebuilds` environment variable.
|
or the `npm_config_sharp_local_prebuilds` environment variable.
|
||||||
|
|
||||||
|
### Prebuilt libvips binaries
|
||||||
|
|
||||||
To install the prebuilt libvips binaries from a custom URL,
|
To install the prebuilt libvips binaries from a custom URL,
|
||||||
set the `sharp_libvips_binary_host` npm config option
|
set the `sharp_libvips_binary_host` npm config option
|
||||||
or the `npm_config_sharp_libvips_binary_host` environment variable.
|
or the `npm_config_sharp_libvips_binary_host` environment variable.
|
||||||
|
|
||||||
|
To install the prebuilt libvips binaries from a directory on the local filesystem,
|
||||||
|
set the `sharp_libvips_local_prebuilds` npm config option
|
||||||
|
or the `npm_config_sharp_libvips_local_prebuilds` environment variable.
|
||||||
|
|
||||||
The version subpath and file name are appended to these.
|
The version subpath and file name are appended to these.
|
||||||
For example, if `sharp_libvips_binary_host` is set to `https://hostname/path`
|
For example, if `sharp_libvips_binary_host` is set to `https://hostname/path`
|
||||||
and the libvips version is `1.2.3` then the resultant URL will be
|
and the libvips version is `1.2.3` then the resultant URL will be
|
||||||
@@ -207,7 +223,8 @@ run the following additional command after `npm install`:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install
|
npm install
|
||||||
SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install --arch=x64 --platform=linux sharp
|
rm -rf node_modules/sharp
|
||||||
|
SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install --arch=x64 --platform=linux --libc=glibc sharp
|
||||||
```
|
```
|
||||||
|
|
||||||
To get the best performance select the largest memory available.
|
To get the best performance select the largest memory available.
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -35,6 +35,7 @@ const hasSharpPrebuild = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const { minimumLibvipsVersion, minimumLibvipsVersionLabelled } = libvips;
|
const { minimumLibvipsVersion, minimumLibvipsVersionLabelled } = libvips;
|
||||||
|
const localLibvipsDir = process.env.npm_config_sharp_libvips_local_prebuilds || '';
|
||||||
const distHost = process.env.npm_config_sharp_libvips_binary_host || 'https://github.com/lovell/sharp-libvips/releases/download';
|
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 distBaseUrl = process.env.npm_config_sharp_dist_base_url || process.env.SHARP_DIST_BASE_URL || `${distHost}/v${minimumLibvipsVersionLabelled}/`;
|
||||||
const installationForced = !!(process.env.npm_config_sharp_install_force || process.env.SHARP_INSTALL_FORCE);
|
const installationForced = !!(process.env.npm_config_sharp_install_force || process.env.SHARP_INSTALL_FORCE);
|
||||||
@@ -42,7 +43,9 @@ const installationForced = !!(process.env.npm_config_sharp_install_force || proc
|
|||||||
const fail = function (err) {
|
const fail = function (err) {
|
||||||
libvips.log(err);
|
libvips.log(err);
|
||||||
if (err.code === 'EACCES') {
|
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('Are you trying to install as a root or sudo user?');
|
||||||
|
libvips.log('- For npm <= v6, try again with the "--unsafe-perm" flag');
|
||||||
|
libvips.log('- For npm >= v8, the user must own the directory "npm install" is run in');
|
||||||
}
|
}
|
||||||
libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
|
libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@@ -156,6 +159,11 @@ try {
|
|||||||
if (fs.existsSync(tarPathCache)) {
|
if (fs.existsSync(tarPathCache)) {
|
||||||
libvips.log(`Using cached ${tarPathCache}`);
|
libvips.log(`Using cached ${tarPathCache}`);
|
||||||
extractTarball(tarPathCache, platformAndArch);
|
extractTarball(tarPathCache, platformAndArch);
|
||||||
|
} else if (localLibvipsDir) {
|
||||||
|
// If localLibvipsDir is given try to use binaries from local directory
|
||||||
|
const tarPathLocal = path.join(path.resolve(localLibvipsDir), `v${minimumLibvipsVersionLabelled}`, tarFilename);
|
||||||
|
libvips.log(`Using local libvips from ${tarPathLocal}`);
|
||||||
|
extractTarball(tarPathLocal, platformAndArch);
|
||||||
} else {
|
} else {
|
||||||
const url = distBaseUrl + tarFilename;
|
const url = distBaseUrl + tarFilename;
|
||||||
libvips.log(`Downloading ${url}`);
|
libvips.log(`Downloading ${url}`);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const blend = {
|
|||||||
* `hard-light`, `soft-light`, `difference`, `exclusion`.
|
* `hard-light`, `soft-light`, `difference`, `exclusion`.
|
||||||
*
|
*
|
||||||
* More information about blend modes can be found at
|
* More information about blend modes can be found at
|
||||||
* https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
|
* https://www.libvips.org/API/current/libvips-conversion.html#VipsBlendMode
|
||||||
* and https://www.cairographics.org/operators/
|
* and https://www.cairographics.org/operators/
|
||||||
*
|
*
|
||||||
* @since 0.22.0
|
* @since 0.22.0
|
||||||
|
|||||||
@@ -309,9 +309,9 @@ function _isStreamInput () {
|
|||||||
* - `size`: Total size of image in bytes, for Stream and Buffer input only
|
* - `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, see example below)
|
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
|
||||||
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
|
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
|
||||||
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation)
|
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://www.libvips.org/API/current/VipsImage.html#VipsInterpretation)
|
||||||
* - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
* - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
||||||
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat)
|
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://www.libvips.org/API/current/VipsImage.html#VipsBandFormat)
|
||||||
* - `density`: Number of pixels per inch (DPI), if present
|
* - `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
|
* - `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
|
* - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
||||||
|
|||||||
@@ -65,7 +65,12 @@ const isRosetta = function () {
|
|||||||
|
|
||||||
const globalLibvipsVersion = function () {
|
const globalLibvipsVersion = function () {
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
const globalLibvipsVersion = spawnSync(`PKG_CONFIG_PATH="${pkgConfigPath()}" pkg-config --modversion vips-cpp`, spawnSyncOptions).stdout;
|
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
||||||
|
...spawnSyncOptions,
|
||||||
|
env: {
|
||||||
|
PKG_CONFIG_PATH: pkgConfigPath()
|
||||||
|
}
|
||||||
|
}).stdout;
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
return (globalLibvipsVersion || '').trim();
|
return (globalLibvipsVersion || '').trim();
|
||||||
} else {
|
} else {
|
||||||
@@ -85,7 +90,10 @@ const removeVendoredLibvips = function () {
|
|||||||
|
|
||||||
const pkgConfigPath = function () {
|
const pkgConfigPath = function () {
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
const brewPkgConfigPath = spawnSync('which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR', spawnSyncOptions).stdout || '';
|
const brewPkgConfigPath = spawnSync(
|
||||||
|
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
||||||
|
spawnSyncOptions
|
||||||
|
).stdout || '';
|
||||||
return [
|
return [
|
||||||
brewPkgConfigPath.trim(),
|
brewPkgConfigPath.trim(),
|
||||||
env.PKG_CONFIG_PATH,
|
env.PKG_CONFIG_PATH,
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ function toFile (fileOut, callback) {
|
|||||||
* Write output to a Buffer.
|
* Write output to a Buffer.
|
||||||
* JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
* JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
||||||
*
|
*
|
||||||
|
* Use {@link toFormat} or one of the format-specific functions such as {@link jpeg}, {@link png} etc. to set the output format.
|
||||||
|
*
|
||||||
* If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
* If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
||||||
*
|
*
|
||||||
* By default all metadata will be removed, which includes EXIF-based orientation.
|
* By default all metadata will be removed, which includes EXIF-based orientation.
|
||||||
@@ -108,6 +110,7 @@ function toFile (fileOut, callback) {
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* sharp(input)
|
* sharp(input)
|
||||||
|
* .png()
|
||||||
* .toBuffer({ resolveWithObject: true })
|
* .toBuffer({ resolveWithObject: true })
|
||||||
* .then(({ data, info }) => { ... })
|
* .then(({ data, info }) => { ... })
|
||||||
* .catch(err => { ... });
|
* .catch(err => { ... });
|
||||||
@@ -516,7 +519,7 @@ function webp (options) {
|
|||||||
* // Convert PNG to GIF
|
* // Convert PNG to GIF
|
||||||
* await sharp(pngBuffer)
|
* await sharp(pngBuffer)
|
||||||
* .gif()
|
* .gif()
|
||||||
* .toBuffer());
|
* .toBuffer();
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // Convert animated WebP to animated GIF
|
* // Convert animated WebP to animated GIF
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ const env = process.env;
|
|||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
const arch = env.npm_config_arch || process.arch;
|
const arch = env.npm_config_arch || process.arch;
|
||||||
const platform = env.npm_config_platform || process.platform;
|
const platform = env.npm_config_platform || process.platform;
|
||||||
/* istanbul ignore next */
|
const libc = process.env.npm_config_libc ||
|
||||||
const libc = (platform === 'linux' && detectLibc.isNonGlibcLinuxSync()) ? detectLibc.familySync() : '';
|
/* istanbul ignore next */
|
||||||
|
(detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '');
|
||||||
|
const libcId = platform !== 'linux' || libc === detectLibc.GLIBC ? '' : libc;
|
||||||
|
|
||||||
const platformId = [`${platform}${libc}`];
|
const platformId = [`${platform}${libcId}`];
|
||||||
|
|
||||||
if (arch === 'arm') {
|
if (arch === 'arm') {
|
||||||
const fallback = process.versions.electron ? '7' : '6';
|
const fallback = process.versions.electron ? '7' : '6';
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ try {
|
|||||||
} else {
|
} else {
|
||||||
const [platform, arch] = platformAndArch.split('-');
|
const [platform, arch] = platformAndArch.split('-');
|
||||||
help.push(
|
help.push(
|
||||||
'- Install with the --verbose flag and look for errors: "npm install --ignore-scripts=false --verbose sharp"',
|
'- Install with verbose logging and look for errors: "npm install --ignore-scripts=false --foreground-scripts --verbose sharp"',
|
||||||
`- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
|
`- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,11 @@ cache(true);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or, when a concurrency is provided, sets
|
* Gets or, when a concurrency is provided, sets
|
||||||
* the number of threads _libvips'_ should create to process each image.
|
* the maximum number of threads _libvips_ should use to process _each image_.
|
||||||
|
* These are from a thread pool managed by glib,
|
||||||
|
* which helps avoid the overhead of creating new threads.
|
||||||
|
*
|
||||||
|
* This method always returns the current concurrency.
|
||||||
*
|
*
|
||||||
* The default value is the number of CPU cores,
|
* The default value is the number of CPU cores,
|
||||||
* except when using glibc-based Linux without jemalloc,
|
* except when using glibc-based Linux without jemalloc,
|
||||||
@@ -111,10 +115,19 @@ cache(true);
|
|||||||
*
|
*
|
||||||
* A value of `0` will reset this to the number of CPU cores.
|
* A value of `0` will reset this to the number of CPU cores.
|
||||||
*
|
*
|
||||||
* The maximum number of images that can be processed in parallel
|
* Some image format libraries spawn additional threads,
|
||||||
* is limited by libuv's `UV_THREADPOOL_SIZE` environment variable.
|
* e.g. libaom manages its own 4 threads when encoding AVIF images,
|
||||||
|
* and these are independent of the value set here.
|
||||||
*
|
*
|
||||||
* This method always returns the current concurrency.
|
* The maximum number of images that sharp can process in parallel
|
||||||
|
* is controlled by libuv's `UV_THREADPOOL_SIZE` environment variable,
|
||||||
|
* which defaults to 4.
|
||||||
|
*
|
||||||
|
* https://nodejs.org/api/cli.html#uv_threadpool_sizesize
|
||||||
|
*
|
||||||
|
* For example, by default, a machine with 8 CPU cores will process
|
||||||
|
* 4 images in parallel and use up to 8 threads per image,
|
||||||
|
* so there will be up to 32 concurrent threads.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const threads = sharp.concurrency(); // 4
|
* const threads = sharp.concurrency(); // 4
|
||||||
|
|||||||
11
package.json
11
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
||||||
"version": "0.30.4",
|
"version": "0.30.5",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://github.com/lovell/sharp",
|
"homepage": "https://github.com/lovell/sharp",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -82,7 +82,8 @@
|
|||||||
"Joris Dugué <zaruike10@gmail.com>",
|
"Joris Dugué <zaruike10@gmail.com>",
|
||||||
"Chris Banks <christopher.bradley.banks@gmail.com>",
|
"Chris Banks <christopher.bradley.banks@gmail.com>",
|
||||||
"Ompal Singh <ompal.hitm09@gmail.com>",
|
"Ompal Singh <ompal.hitm09@gmail.com>",
|
||||||
"Brodan <christopher.hranj@gmail.com"
|
"Brodan <christopher.hranj@gmail.com",
|
||||||
|
"Ankur Parihar <ankur.github@gmail.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && 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)",
|
||||||
@@ -129,8 +130,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
"detect-libc": "^2.0.1",
|
"detect-libc": "^2.0.1",
|
||||||
"node-addon-api": "^4.3.0",
|
"node-addon-api": "^5.0.0",
|
||||||
"prebuild-install": "^7.0.1",
|
"prebuild-install": "^7.1.0",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"simple-get": "^4.0.1",
|
"simple-get": "^4.0.1",
|
||||||
"tar-fs": "^2.1.1",
|
"tar-fs": "^2.1.1",
|
||||||
@@ -144,7 +145,7 @@
|
|||||||
"exif-reader": "^1.0.3",
|
"exif-reader": "^1.0.3",
|
||||||
"icc": "^2.0.0",
|
"icc": "^2.0.0",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"mocha": "^9.2.2",
|
"mocha": "^10.0.0",
|
||||||
"mock-fs": "^5.1.2",
|
"mock-fs": "^5.1.2",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"prebuild": "^11.0.3",
|
"prebuild": "^11.0.3",
|
||||||
|
|||||||
@@ -95,16 +95,18 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
if (baton->rotateBeforePreExtract) {
|
if (baton->rotateBeforePreExtract) {
|
||||||
if (rotation != VIPS_ANGLE_D0) {
|
if (rotation != VIPS_ANGLE_D0) {
|
||||||
image = image.rot(rotation);
|
image = image.rot(rotation);
|
||||||
if (flip) {
|
}
|
||||||
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
if (flip) {
|
||||||
flip = FALSE;
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
||||||
}
|
}
|
||||||
if (flop) {
|
if (flop) {
|
||||||
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||||
flop = FALSE;
|
}
|
||||||
}
|
if (rotation != VIPS_ANGLE_D0 || flip || flop) {
|
||||||
image = sharp::RemoveExifOrientation(image);
|
image = sharp::RemoveExifOrientation(image);
|
||||||
}
|
}
|
||||||
|
flop = FALSE;
|
||||||
|
flip = FALSE;
|
||||||
if (baton->rotationAngle != 0.0) {
|
if (baton->rotationAngle != 0.0) {
|
||||||
MultiPageUnsupported(nPages, "Rotate");
|
MultiPageUnsupported(nPages, "Rotate");
|
||||||
std::vector<double> background;
|
std::vector<double> background;
|
||||||
|
|||||||
@@ -168,14 +168,51 @@ describe('Partial image extraction', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Rotate with EXIF mirroring then extract', function (done) {
|
describe('Apply exif orientation and mirroring then extract', () => {
|
||||||
sharp(fixtures.inputJpgWithLandscapeExif7)
|
[
|
||||||
.rotate()
|
{
|
||||||
.extract({ left: 0, top: 208, width: 60, height: 40 })
|
name: 'EXIF-1',
|
||||||
.toBuffer(function (err, data) {
|
image: fixtures.inputJpgWithLandscapeExif1
|
||||||
if (err) throw err;
|
},
|
||||||
fixtures.assertSimilar(fixtures.expected('rotate-mirror-extract.jpg'), data, done);
|
{
|
||||||
|
name: 'EXIF-2',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EXIF-3',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EXIF-4',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EXIF-5',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EXIF-6',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EXIF-7',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EXIF-8',
|
||||||
|
image: fixtures.inputJpgWithLandscapeExif8
|
||||||
|
}
|
||||||
|
].forEach(({ name, image }) => {
|
||||||
|
it(name, function (done) {
|
||||||
|
sharp(image)
|
||||||
|
.rotate()
|
||||||
|
.extract({ left: 0, top: 208, width: 60, height: 40 })
|
||||||
|
.toBuffer(function (err, data) {
|
||||||
|
if (err) throw err;
|
||||||
|
fixtures.assertSimilar(fixtures.expected('rotate-mirror-extract.jpg'), data, done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Invalid parameters', function () {
|
describe('Invalid parameters', function () {
|
||||||
|
|||||||
@@ -61,4 +61,28 @@ describe('Platform-detection', function () {
|
|||||||
delete process.env.npm_config_arch;
|
delete process.env.npm_config_arch;
|
||||||
delete process.versions.electron;
|
delete process.versions.electron;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Can override libc if platform is linux', function () {
|
||||||
|
process.env.npm_config_platform = 'linux';
|
||||||
|
process.env.npm_config_libc = 'test';
|
||||||
|
assert.strictEqual('linuxtest', platform().split('-')[0]);
|
||||||
|
delete process.env.npm_config_platform;
|
||||||
|
delete process.env.npm_config_libc;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handles libc value "glibc" as default linux', function () {
|
||||||
|
process.env.npm_config_platform = 'linux';
|
||||||
|
process.env.npm_config_libc = 'glibc';
|
||||||
|
assert.strictEqual('linux', platform().split('-')[0]);
|
||||||
|
delete process.env.npm_config_platform;
|
||||||
|
delete process.env.npm_config_libc;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Discards libc value on non-linux platform', function () {
|
||||||
|
process.env.npm_config_platform = 'win32';
|
||||||
|
process.env.npm_config_libc = 'gnuwin32';
|
||||||
|
assert.strictEqual('win32', platform().split('-')[0]);
|
||||||
|
delete process.env.npm_config_platform;
|
||||||
|
delete process.env.npm_config_libc;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user