sharp 0.30.5 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/binding.gyp +4 -3
- package/lib/composite.js +14 -0
- package/lib/constructor.js +41 -4
- package/lib/input.js +95 -3
- package/lib/libvips.js +1 -0
- package/lib/operation.js +57 -12
- package/lib/output.js +87 -23
- package/lib/resize.js +90 -13
- package/lib/sharp.js +3 -0
- package/lib/utility.js +4 -0
- package/package.json +25 -23
- package/src/common.cc +95 -45
- package/src/common.h +33 -15
- package/src/libvips/cplusplus/VConnection.cpp +0 -1
- package/src/libvips/cplusplus/VError.cpp +0 -1
- package/src/libvips/cplusplus/VImage.cpp +27 -2
- package/src/libvips/cplusplus/VInterpolate.cpp +0 -1
- package/src/libvips/cplusplus/VRegion.cpp +27 -0
- package/src/libvips/cplusplus/vips-operators.cpp +16 -1
- package/src/operations.cc +69 -25
- package/src/operations.h +7 -2
- package/src/pipeline.cc +162 -164
- package/src/pipeline.h +18 -5
- package/src/sharp.cc +0 -1
- package/src/utilities.cc +13 -2
package/lib/output.js
CHANGED
|
@@ -10,6 +10,9 @@ const formats = new Map([
|
|
|
10
10
|
['avif', 'avif'],
|
|
11
11
|
['jpeg', 'jpeg'],
|
|
12
12
|
['jpg', 'jpeg'],
|
|
13
|
+
['jpe', 'jpeg'],
|
|
14
|
+
['tile', 'tile'],
|
|
15
|
+
['dz', 'tile'],
|
|
13
16
|
['png', 'png'],
|
|
14
17
|
['raw', 'raw'],
|
|
15
18
|
['tiff', 'tiff'],
|
|
@@ -55,6 +58,7 @@ const bitdepthFromColourCount = (colours) => 1 << 31 - Math.clz32(Math.ceil(Math
|
|
|
55
58
|
* `info` contains the output image `format`, `size` (bytes), `width`, `height`,
|
|
56
59
|
* `channels` and `premultiplied` (indicating if premultiplication was used).
|
|
57
60
|
* When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
|
61
|
+
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
|
58
62
|
* @returns {Promise<Object>} - when no callback is provided
|
|
59
63
|
* @throws {Error} Invalid parameters
|
|
60
64
|
*/
|
|
@@ -95,6 +99,7 @@ function toFile (fileOut, callback) {
|
|
|
95
99
|
* - `info` contains the output image `format`, `size` (bytes), `width`, `height`,
|
|
96
100
|
* `channels` and `premultiplied` (indicating if premultiplication was used).
|
|
97
101
|
* When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
|
102
|
+
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
|
98
103
|
*
|
|
99
104
|
* A `Promise` is returned when `callback` is not provided.
|
|
100
105
|
*
|
|
@@ -402,6 +407,14 @@ function png (options) {
|
|
|
402
407
|
if (is.defined(options.adaptiveFiltering)) {
|
|
403
408
|
this._setBooleanOption('pngAdaptiveFiltering', options.adaptiveFiltering);
|
|
404
409
|
}
|
|
410
|
+
const colours = options.colours || options.colors;
|
|
411
|
+
if (is.defined(colours)) {
|
|
412
|
+
if (is.integer(colours) && is.inRange(colours, 2, 256)) {
|
|
413
|
+
this.options.pngBitdepth = bitdepthFromColourCount(colours);
|
|
414
|
+
} else {
|
|
415
|
+
throw is.invalidParameterError('colours', 'integer between 2 and 256', colours);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
405
418
|
if (is.defined(options.palette)) {
|
|
406
419
|
this._setBooleanOption('pngPalette', options.palette);
|
|
407
420
|
} else if ([options.quality, options.effort, options.colours, options.colors, options.dither].some(is.defined)) {
|
|
@@ -422,14 +435,6 @@ function png (options) {
|
|
|
422
435
|
throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort);
|
|
423
436
|
}
|
|
424
437
|
}
|
|
425
|
-
const colours = options.colours || options.colors;
|
|
426
|
-
if (is.defined(colours)) {
|
|
427
|
-
if (is.integer(colours) && is.inRange(colours, 2, 256)) {
|
|
428
|
-
this.options.pngBitdepth = bitdepthFromColourCount(colours);
|
|
429
|
-
} else {
|
|
430
|
-
throw is.invalidParameterError('colours', 'integer between 2 and 256', colours);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
438
|
if (is.defined(options.dither)) {
|
|
434
439
|
if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) {
|
|
435
440
|
this.options.pngDither = options.dither;
|
|
@@ -466,6 +471,8 @@ function png (options) {
|
|
|
466
471
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 6 (slowest)
|
|
467
472
|
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
|
468
473
|
* @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
|
|
474
|
+
* @param {boolean} [options.minSize=false] - prevent use of animation key frames to minimise file size (slow)
|
|
475
|
+
* @param {boolean} [options.mixed=false] - allow mixture of lossy and lossless animation frames (slow)
|
|
469
476
|
* @param {boolean} [options.force=true] - force WebP output, otherwise attempt to use input format
|
|
470
477
|
* @returns {Sharp}
|
|
471
478
|
* @throws {Error} Invalid options
|
|
@@ -495,14 +502,19 @@ function webp (options) {
|
|
|
495
502
|
if (is.defined(options.smartSubsample)) {
|
|
496
503
|
this._setBooleanOption('webpSmartSubsample', options.smartSubsample);
|
|
497
504
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
this.options.webpEffort = effort;
|
|
505
|
+
if (is.defined(options.effort)) {
|
|
506
|
+
if (is.integer(options.effort) && is.inRange(options.effort, 0, 6)) {
|
|
507
|
+
this.options.webpEffort = options.effort;
|
|
502
508
|
} else {
|
|
503
|
-
throw is.invalidParameterError('effort', 'integer between 0 and 6', effort);
|
|
509
|
+
throw is.invalidParameterError('effort', 'integer between 0 and 6', options.effort);
|
|
504
510
|
}
|
|
505
511
|
}
|
|
512
|
+
if (is.defined(options.minSize)) {
|
|
513
|
+
this._setBooleanOption('webpMinSize', options.minSize);
|
|
514
|
+
}
|
|
515
|
+
if (is.defined(options.mixed)) {
|
|
516
|
+
this._setBooleanOption('webpMixed', options.mixed);
|
|
517
|
+
}
|
|
506
518
|
}
|
|
507
519
|
trySetAnimationOptions(options, this.options);
|
|
508
520
|
return this._updateFormatOut('webp', options);
|
|
@@ -513,6 +525,8 @@ function webp (options) {
|
|
|
513
525
|
*
|
|
514
526
|
* The first entry in the palette is reserved for transparency.
|
|
515
527
|
*
|
|
528
|
+
* The palette of the input image will be re-used if possible.
|
|
529
|
+
*
|
|
516
530
|
* @since 0.30.0
|
|
517
531
|
*
|
|
518
532
|
* @example
|
|
@@ -534,6 +548,8 @@ function webp (options) {
|
|
|
534
548
|
* .toBuffer();
|
|
535
549
|
*
|
|
536
550
|
* @param {Object} [options] - output options
|
|
551
|
+
* @param {boolean} [options.reoptimise=false] - always generate new palettes (slow), re-use existing by default
|
|
552
|
+
* @param {boolean} [options.reoptimize=false] - alternative spelling of `options.reoptimise`
|
|
537
553
|
* @param {number} [options.colours=256] - maximum number of palette entries, including transparency, between 2 and 256
|
|
538
554
|
* @param {number} [options.colors=256] - alternative spelling of `options.colours`
|
|
539
555
|
* @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 10 (slowest)
|
|
@@ -546,6 +562,11 @@ function webp (options) {
|
|
|
546
562
|
*/
|
|
547
563
|
function gif (options) {
|
|
548
564
|
if (is.object(options)) {
|
|
565
|
+
if (is.defined(options.reoptimise)) {
|
|
566
|
+
this._setBooleanOption('gifReoptimise', options.reoptimise);
|
|
567
|
+
} else if (is.defined(options.reoptimize)) {
|
|
568
|
+
this._setBooleanOption('gifReoptimise', options.reoptimize);
|
|
569
|
+
}
|
|
549
570
|
const colours = options.colours || options.colors;
|
|
550
571
|
if (is.defined(colours)) {
|
|
551
572
|
if (is.integer(colours) && is.inRange(colours, 2, 256)) {
|
|
@@ -702,7 +723,7 @@ function trySetAnimationOptions (source, target) {
|
|
|
702
723
|
* @param {Object} [options] - output options
|
|
703
724
|
* @param {number} [options.quality=80] - quality, integer 1-100
|
|
704
725
|
* @param {boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
|
|
705
|
-
* @param {string} [options.compression='jpeg'] - compression options:
|
|
726
|
+
* @param {string} [options.compression='jpeg'] - compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k
|
|
706
727
|
* @param {string} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float
|
|
707
728
|
* @param {boolean} [options.pyramid=false] - write an image pyramid
|
|
708
729
|
* @param {boolean} [options.tile=false] - write a tiled tiff
|
|
@@ -770,10 +791,10 @@ function tiff (options) {
|
|
|
770
791
|
}
|
|
771
792
|
// compression
|
|
772
793
|
if (is.defined(options.compression)) {
|
|
773
|
-
if (is.string(options.compression) && is.inArray(options.compression, ['
|
|
794
|
+
if (is.string(options.compression) && is.inArray(options.compression, ['none', 'jpeg', 'deflate', 'packbits', 'ccittfax4', 'lzw', 'webp', 'zstd', 'jp2k'])) {
|
|
774
795
|
this.options.tiffCompression = options.compression;
|
|
775
796
|
} else {
|
|
776
|
-
throw is.invalidParameterError('compression', 'one of:
|
|
797
|
+
throw is.invalidParameterError('compression', 'one of: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k', options.compression);
|
|
777
798
|
}
|
|
778
799
|
}
|
|
779
800
|
// predictor
|
|
@@ -804,6 +825,16 @@ function tiff (options) {
|
|
|
804
825
|
*
|
|
805
826
|
* AVIF image sequences are not supported.
|
|
806
827
|
*
|
|
828
|
+
* @example
|
|
829
|
+
* const data = await sharp(input)
|
|
830
|
+
* .avif({ effort: 2 })
|
|
831
|
+
* .toBuffer();
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* const data = await sharp(input)
|
|
835
|
+
* .avif({ lossless: true })
|
|
836
|
+
* .toBuffer();
|
|
837
|
+
*
|
|
807
838
|
* @since 0.27.0
|
|
808
839
|
*
|
|
809
840
|
* @param {Object} [options] - output options
|
|
@@ -821,9 +852,14 @@ function avif (options) {
|
|
|
821
852
|
/**
|
|
822
853
|
* Use these HEIF options for output image.
|
|
823
854
|
*
|
|
824
|
-
* Support for patent-encumbered HEIC images requires the use of a
|
|
855
|
+
* Support for patent-encumbered HEIC images using `hevc` compression requires the use of a
|
|
825
856
|
* globally-installed libvips compiled with support for libheif, libde265 and x265.
|
|
826
857
|
*
|
|
858
|
+
* @example
|
|
859
|
+
* const data = await sharp(input)
|
|
860
|
+
* .heif({ compression: 'hevc' })
|
|
861
|
+
* .toBuffer();
|
|
862
|
+
*
|
|
827
863
|
* @since 0.23.0
|
|
828
864
|
*
|
|
829
865
|
* @param {Object} [options] - output options
|
|
@@ -864,12 +900,6 @@ function heif (options) {
|
|
|
864
900
|
} else {
|
|
865
901
|
throw is.invalidParameterError('effort', 'integer between 0 and 9', options.effort);
|
|
866
902
|
}
|
|
867
|
-
} else if (is.defined(options.speed)) {
|
|
868
|
-
if (is.integer(options.speed) && is.inRange(options.speed, 0, 9)) {
|
|
869
|
-
this.options.heifEffort = 9 - options.speed;
|
|
870
|
-
} else {
|
|
871
|
-
throw is.invalidParameterError('speed', 'integer between 0 and 9', options.speed);
|
|
872
|
-
}
|
|
873
903
|
}
|
|
874
904
|
if (is.defined(options.chromaSubsampling)) {
|
|
875
905
|
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
|
|
@@ -923,9 +953,12 @@ function raw (options) {
|
|
|
923
953
|
|
|
924
954
|
/**
|
|
925
955
|
* Use tile-based deep zoom (image pyramid) output.
|
|
956
|
+
*
|
|
926
957
|
* Set the format and options for tile images via the `toFormat`, `jpeg`, `png` or `webp` functions.
|
|
927
958
|
* Use a `.zip` or `.szi` file extension with `toFile` to write to a compressed archive file format.
|
|
928
959
|
*
|
|
960
|
+
* The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`.
|
|
961
|
+
*
|
|
929
962
|
* @example
|
|
930
963
|
* sharp('input.tiff')
|
|
931
964
|
* .png()
|
|
@@ -937,6 +970,17 @@ function raw (options) {
|
|
|
937
970
|
* // output_files contains 512x512 tiles grouped by zoom level
|
|
938
971
|
* });
|
|
939
972
|
*
|
|
973
|
+
* @example
|
|
974
|
+
* const zipFileWithTiles = await sharp(input)
|
|
975
|
+
* .tile({ basename: "tiles" })
|
|
976
|
+
* .toBuffer();
|
|
977
|
+
*
|
|
978
|
+
* @example
|
|
979
|
+
* const iiififier = sharp().tile({ layout: "iiif" });
|
|
980
|
+
* readableStream
|
|
981
|
+
* .pipe(iiififier)
|
|
982
|
+
* .pipe(writeableStream);
|
|
983
|
+
*
|
|
940
984
|
* @param {Object} [options]
|
|
941
985
|
* @param {number} [options.size=256] tile size in pixels, a value between 1 and 8192.
|
|
942
986
|
* @param {number} [options.overlap=0] tile overlap in pixels, a value between 0 and 8192.
|
|
@@ -949,6 +993,7 @@ function raw (options) {
|
|
|
949
993
|
* @param {boolean} [options.centre=false] centre image in tile.
|
|
950
994
|
* @param {boolean} [options.center=false] alternative spelling of centre.
|
|
951
995
|
* @param {string} [options.id='https://example.com/iiif'] when `layout` is `iiif`/`iiif3`, sets the `@id`/`id` attribute of `info.json`
|
|
996
|
+
* @param {string} [options.basename] the name of the directory within the zip file when container is `zip`.
|
|
952
997
|
* @returns {Sharp}
|
|
953
998
|
* @throws {Error} Invalid parameters
|
|
954
999
|
*/
|
|
@@ -1030,6 +1075,14 @@ function tile (options) {
|
|
|
1030
1075
|
throw is.invalidParameterError('id', 'string', options.id);
|
|
1031
1076
|
}
|
|
1032
1077
|
}
|
|
1078
|
+
// Basename for zip container
|
|
1079
|
+
if (is.defined(options.basename)) {
|
|
1080
|
+
if (is.string(options.basename)) {
|
|
1081
|
+
this.options.tileBasename = options.basename;
|
|
1082
|
+
} else {
|
|
1083
|
+
throw is.invalidParameterError('basename', 'string', options.basename);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1033
1086
|
}
|
|
1034
1087
|
// Format
|
|
1035
1088
|
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
|
|
@@ -1047,6 +1100,17 @@ function tile (options) {
|
|
|
1047
1100
|
* The clock starts when libvips opens an input image for processing.
|
|
1048
1101
|
* Time spent waiting for a libuv thread to become available is not included.
|
|
1049
1102
|
*
|
|
1103
|
+
* @example
|
|
1104
|
+
* // Ensure processing takes no longer than 3 seconds
|
|
1105
|
+
* try {
|
|
1106
|
+
* const data = await sharp(input)
|
|
1107
|
+
* .blur(1000)
|
|
1108
|
+
* .timeout({ seconds: 3 })
|
|
1109
|
+
* .toBuffer();
|
|
1110
|
+
* } catch (err) {
|
|
1111
|
+
* if (err.message.includes('timeout')) { ... }
|
|
1112
|
+
* }
|
|
1113
|
+
*
|
|
1050
1114
|
* @since 0.29.2
|
|
1051
1115
|
*
|
|
1052
1116
|
* @param {Object} options
|
package/lib/resize.js
CHANGED
|
@@ -92,6 +92,13 @@ function isRotationExpected (options) {
|
|
|
92
92
|
return (options.angle % 360) !== 0 || options.useExifOrientation === true || options.rotationAngle !== 0;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
98
|
+
function isResizeExpected (options) {
|
|
99
|
+
return options.width !== -1 || options.height !== -1;
|
|
100
|
+
}
|
|
101
|
+
|
|
95
102
|
/**
|
|
96
103
|
* Resize image to `width`, `height` or `width x height`.
|
|
97
104
|
*
|
|
@@ -123,6 +130,9 @@ function isRotationExpected (options) {
|
|
|
123
130
|
* - `lanczos2`: Use a [Lanczos kernel](https://en.wikipedia.org/wiki/Lanczos_resampling#Lanczos_kernel) with `a=2`.
|
|
124
131
|
* - `lanczos3`: Use a Lanczos kernel with `a=3` (the default).
|
|
125
132
|
*
|
|
133
|
+
* Only one resize can occur per pipeline.
|
|
134
|
+
* Previous calls to `resize` in the same pipeline will be ignored.
|
|
135
|
+
*
|
|
126
136
|
* @example
|
|
127
137
|
* sharp(input)
|
|
128
138
|
* .resize({ width: 100 })
|
|
@@ -211,7 +221,7 @@ function isRotationExpected (options) {
|
|
|
211
221
|
* @param {String} [options.height] - alternative means of specifying `height`. If both are present this take priority.
|
|
212
222
|
* @param {String} [options.fit='cover'] - how the image should be resized to fit both provided dimensions, one of `cover`, `contain`, `fill`, `inside` or `outside`.
|
|
213
223
|
* @param {String} [options.position='centre'] - position, gravity or strategy to use when `fit` is `cover` or `contain`.
|
|
214
|
-
* @param {String|Object} [options.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour when
|
|
224
|
+
* @param {String|Object} [options.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour when `fit` is `contain`, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
|
|
215
225
|
* @param {String} [options.kernel='lanczos3'] - the kernel to use for image reduction.
|
|
216
226
|
* @param {Boolean} [options.withoutEnlargement=false] - do not enlarge if the width *or* height are already less than the specified dimensions, equivalent to GraphicsMagick's `>` geometry option.
|
|
217
227
|
* @param {Boolean} [options.withoutReduction=false] - do not reduce if the width *or* height are already greater than the specified dimensions, equivalent to GraphicsMagick's `<` geometry option.
|
|
@@ -220,6 +230,9 @@ function isRotationExpected (options) {
|
|
|
220
230
|
* @throws {Error} Invalid parameters
|
|
221
231
|
*/
|
|
222
232
|
function resize (width, height, options) {
|
|
233
|
+
if (isResizeExpected(this.options)) {
|
|
234
|
+
this.options.debuglog('ignoring previous resize options');
|
|
235
|
+
}
|
|
223
236
|
if (is.defined(width)) {
|
|
224
237
|
if (is.object(width) && !is.defined(options)) {
|
|
225
238
|
options = width;
|
|
@@ -300,6 +313,9 @@ function resize (width, height, options) {
|
|
|
300
313
|
this._setBooleanOption('fastShrinkOnLoad', options.fastShrinkOnLoad);
|
|
301
314
|
}
|
|
302
315
|
}
|
|
316
|
+
if (isRotationExpected(this.options) && isResizeExpected(this.options)) {
|
|
317
|
+
this.options.rotateBeforePreExtract = true;
|
|
318
|
+
}
|
|
303
319
|
return this;
|
|
304
320
|
}
|
|
305
321
|
|
|
@@ -412,7 +428,10 @@ function extend (extend) {
|
|
|
412
428
|
* @throws {Error} Invalid parameters
|
|
413
429
|
*/
|
|
414
430
|
function extract (options) {
|
|
415
|
-
const suffix = this.options
|
|
431
|
+
const suffix = isResizeExpected(this.options) || isRotationExpected(this.options) ? 'Post' : 'Pre';
|
|
432
|
+
if (this.options[`width${suffix}`] !== -1) {
|
|
433
|
+
this.options.debuglog('ignoring previous extract options');
|
|
434
|
+
}
|
|
416
435
|
['left', 'top', 'width', 'height'].forEach(function (name) {
|
|
417
436
|
const value = options[name];
|
|
418
437
|
if (is.integer(value) && value >= 0) {
|
|
@@ -422,32 +441,90 @@ function extract (options) {
|
|
|
422
441
|
}
|
|
423
442
|
}, this);
|
|
424
443
|
// Ensure existing rotation occurs before pre-resize extraction
|
|
425
|
-
if (
|
|
426
|
-
this.options.
|
|
444
|
+
if (isRotationExpected(this.options) && !isResizeExpected(this.options)) {
|
|
445
|
+
if (this.options.widthPre === -1 || this.options.widthPost === -1) {
|
|
446
|
+
this.options.rotateBeforePreExtract = true;
|
|
447
|
+
}
|
|
427
448
|
}
|
|
428
449
|
return this;
|
|
429
450
|
}
|
|
430
451
|
|
|
431
452
|
/**
|
|
432
|
-
* Trim
|
|
433
|
-
*
|
|
453
|
+
* Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
|
454
|
+
*
|
|
455
|
+
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
|
456
|
+
*
|
|
457
|
+
* If the result of this operation would trim an image to nothing then no change is made.
|
|
434
458
|
*
|
|
435
459
|
* The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
|
|
436
460
|
* will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
|
437
461
|
*
|
|
438
|
-
* @
|
|
462
|
+
* @example
|
|
463
|
+
* // Trim pixels with a colour similar to that of the top-left pixel.
|
|
464
|
+
* sharp(input)
|
|
465
|
+
* .trim()
|
|
466
|
+
* .toFile(output, function(err, info) {
|
|
467
|
+
* ...
|
|
468
|
+
* });
|
|
469
|
+
* @example
|
|
470
|
+
* // Trim pixels with the exact same colour as that of the top-left pixel.
|
|
471
|
+
* sharp(input)
|
|
472
|
+
* .trim(0)
|
|
473
|
+
* .toFile(output, function(err, info) {
|
|
474
|
+
* ...
|
|
475
|
+
* });
|
|
476
|
+
* @example
|
|
477
|
+
* // Trim only pixels with a similar colour to red.
|
|
478
|
+
* sharp(input)
|
|
479
|
+
* .trim("#FF0000")
|
|
480
|
+
* .toFile(output, function(err, info) {
|
|
481
|
+
* ...
|
|
482
|
+
* });
|
|
483
|
+
* @example
|
|
484
|
+
* // Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
|
|
485
|
+
* sharp(input)
|
|
486
|
+
* .trim({
|
|
487
|
+
* background: "yellow",
|
|
488
|
+
* threshold: 42,
|
|
489
|
+
* })
|
|
490
|
+
* .toFile(output, function(err, info) {
|
|
491
|
+
* ...
|
|
492
|
+
* });
|
|
493
|
+
*
|
|
494
|
+
* @param {string|number|Object} trim - the specific background colour to trim, the threshold for doing so or an Object with both.
|
|
495
|
+
* @param {string|Object} [trim.background='top-left pixel'] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
|
|
496
|
+
* @param {number} [trim.threshold=10] - the allowed difference from the above colour, a positive number.
|
|
439
497
|
* @returns {Sharp}
|
|
440
498
|
* @throws {Error} Invalid parameters
|
|
441
499
|
*/
|
|
442
|
-
function trim (
|
|
443
|
-
if (!is.defined(
|
|
500
|
+
function trim (trim) {
|
|
501
|
+
if (!is.defined(trim)) {
|
|
502
|
+
this.options.trimThreshold = 10;
|
|
503
|
+
} else if (is.string(trim)) {
|
|
504
|
+
this._setBackgroundColourOption('trimBackground', trim);
|
|
444
505
|
this.options.trimThreshold = 10;
|
|
445
|
-
} else if (is.number(
|
|
446
|
-
|
|
506
|
+
} else if (is.number(trim)) {
|
|
507
|
+
if (trim >= 0) {
|
|
508
|
+
this.options.trimThreshold = trim;
|
|
509
|
+
} else {
|
|
510
|
+
throw is.invalidParameterError('threshold', 'positive number', trim);
|
|
511
|
+
}
|
|
512
|
+
} else if (is.object(trim)) {
|
|
513
|
+
this._setBackgroundColourOption('trimBackground', trim.background);
|
|
514
|
+
|
|
515
|
+
if (!is.defined(trim.threshold)) {
|
|
516
|
+
this.options.trimThreshold = 10;
|
|
517
|
+
} else if (is.number(trim.threshold)) {
|
|
518
|
+
if (trim.threshold >= 0) {
|
|
519
|
+
this.options.trimThreshold = trim.threshold;
|
|
520
|
+
} else {
|
|
521
|
+
throw is.invalidParameterError('threshold', 'positive number', trim);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
447
524
|
} else {
|
|
448
|
-
throw is.invalidParameterError('
|
|
525
|
+
throw is.invalidParameterError('trim', 'string, number or object', trim);
|
|
449
526
|
}
|
|
450
|
-
if (
|
|
527
|
+
if (isRotationExpected(this.options)) {
|
|
451
528
|
this.options.rotateBeforePreExtract = true;
|
|
452
529
|
}
|
|
453
530
|
return this;
|
package/lib/sharp.js
CHANGED
|
@@ -12,6 +12,9 @@ try {
|
|
|
12
12
|
help.push('- Update Homebrew: "brew update && brew upgrade vips"');
|
|
13
13
|
} else {
|
|
14
14
|
const [platform, arch] = platformAndArch.split('-');
|
|
15
|
+
if (platform === 'linux' && /Module did not self-register/.test(err.message)) {
|
|
16
|
+
help.push('- Using worker threads? See https://sharp.pixelplumbing.com/install#worker-threads');
|
|
17
|
+
}
|
|
15
18
|
help.push(
|
|
16
19
|
'- Install with verbose logging and look for errors: "npm install --ignore-scripts=false --foreground-scripts --verbose sharp"',
|
|
17
20
|
`- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
|
package/lib/utility.js
CHANGED
|
@@ -17,6 +17,10 @@ const sharp = require('./sharp');
|
|
|
17
17
|
* @returns {Object}
|
|
18
18
|
*/
|
|
19
19
|
const format = sharp.format();
|
|
20
|
+
format.heif.output.alias = ['avif', 'heic'];
|
|
21
|
+
format.jpeg.output.alias = ['jpe', 'jpg'];
|
|
22
|
+
format.tiff.output.alias = ['tif'];
|
|
23
|
+
format.jp2k.output.alias = ['j2c', 'j2k', 'jp2', 'jpx'];
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
26
|
* An Object containing the available interpolators and their proper values
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sharp",
|
|
3
3
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.31.0",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -83,7 +83,9 @@
|
|
|
83
83
|
"Chris Banks <christopher.bradley.banks@gmail.com>",
|
|
84
84
|
"Ompal Singh <ompal.hitm09@gmail.com>",
|
|
85
85
|
"Brodan <christopher.hranj@gmail.com",
|
|
86
|
-
"Ankur Parihar <ankur.github@gmail.com>"
|
|
86
|
+
"Ankur Parihar <ankur.github@gmail.com>",
|
|
87
|
+
"Brahim Ait elhaj <brahima@gmail.com>",
|
|
88
|
+
"Mart Jansink <m.jansink@gmail.com>"
|
|
87
89
|
],
|
|
88
90
|
"scripts": {
|
|
89
91
|
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
|
|
@@ -131,55 +133,55 @@
|
|
|
131
133
|
"color": "^4.2.3",
|
|
132
134
|
"detect-libc": "^2.0.1",
|
|
133
135
|
"node-addon-api": "^5.0.0",
|
|
134
|
-
"prebuild-install": "^7.1.
|
|
136
|
+
"prebuild-install": "^7.1.1",
|
|
135
137
|
"semver": "^7.3.7",
|
|
136
138
|
"simple-get": "^4.0.1",
|
|
137
139
|
"tar-fs": "^2.1.1",
|
|
138
140
|
"tunnel-agent": "^0.6.0"
|
|
139
141
|
},
|
|
140
142
|
"devDependencies": {
|
|
141
|
-
"async": "^3.2.
|
|
143
|
+
"async": "^3.2.4",
|
|
142
144
|
"cc": "^3.0.1",
|
|
143
|
-
"
|
|
144
|
-
"documentation": "^13.2.5",
|
|
145
|
+
"documentation": "^14.0.0",
|
|
145
146
|
"exif-reader": "^1.0.3",
|
|
147
|
+
"extract-zip": "^2.0.1",
|
|
146
148
|
"icc": "^2.0.0",
|
|
147
149
|
"license-checker": "^25.0.1",
|
|
148
150
|
"mocha": "^10.0.0",
|
|
149
|
-
"mock-fs": "^5.1.
|
|
151
|
+
"mock-fs": "^5.1.4",
|
|
150
152
|
"nyc": "^15.1.0",
|
|
151
|
-
"prebuild": "^11.0.
|
|
153
|
+
"prebuild": "^11.0.4",
|
|
152
154
|
"rimraf": "^3.0.2",
|
|
153
155
|
"semistandard": "^16.0.1"
|
|
154
156
|
},
|
|
155
157
|
"license": "Apache-2.0",
|
|
156
158
|
"config": {
|
|
157
|
-
"libvips": "8.
|
|
159
|
+
"libvips": "8.13.1",
|
|
158
160
|
"integrity": {
|
|
159
|
-
"darwin-arm64v8": "sha512-
|
|
160
|
-
"darwin-x64": "sha512-
|
|
161
|
-
"linux-arm64v8": "sha512-
|
|
162
|
-
"linux-armv6": "sha512-
|
|
163
|
-
"linux-armv7": "sha512-
|
|
164
|
-
"linux-x64": "sha512-
|
|
165
|
-
"linuxmusl-arm64v8": "sha512-
|
|
166
|
-
"linuxmusl-x64": "sha512-
|
|
167
|
-
"win32-arm64v8": "sha512-
|
|
168
|
-
"win32-ia32": "sha512-
|
|
169
|
-
"win32-x64": "sha512-
|
|
161
|
+
"darwin-arm64v8": "sha512-JdpGTx67RDbvRkg3ljFvTzqoq+oBXmMdDFEp0expDYXmP5HLH+GCkikmsROlGltgfKE2KqL/qwpxTEhIwMK/3A==",
|
|
162
|
+
"darwin-x64": "sha512-0Oh4/hEDnzV+X8MiiyUQ4G/Zh/MHw9rKstfuX0P1czgaxS2hX8Pxdbzdk1oqwTOEYVEGO/hMm9ItCVZ3RVPPaA==",
|
|
163
|
+
"linux-arm64v8": "sha512-9pSlPzEojt6ue5vXfASNMhQO1YS1p4i4Wydu+bzOfMtIPSBRXbu/+y8WELbbo03Ts7pftm9KtrMHitCVdy5EXw==",
|
|
164
|
+
"linux-armv6": "sha512-sv2FqS/ggpQly7h5/+nh8txQDulolE5ptaE90PO7iwfTont8N42pudeqootWKsuf0fRmkW4M92184VfVVYCvGw==",
|
|
165
|
+
"linux-armv7": "sha512-LmQIB8FDfasK6BsFhnE7ZI3LMlxh/rF5tZRNQ/uoTbF2xrtWQqqgiZgCifJByiEM+1tR7RxwNdnjxZhWvM9WmQ==",
|
|
166
|
+
"linux-x64": "sha512-JBRf8WBnlVw/K1jpSvmeZpnGZGjeqhG2NDEiQV/hUze3zgDGwDza4oiworaQExQmKcDrc2LJKF14Nsz1qQSNJw==",
|
|
167
|
+
"linuxmusl-arm64v8": "sha512-yzUQO5isDwsRpEUxbMXBeWp0sKhWghebrSK46SUF5mvB/kq6hZ7JbRuJ2aZjE84K/HUTyuCc0kE+M3m8naOs+g==",
|
|
168
|
+
"linuxmusl-x64": "sha512-H3Vz1QaaZ6X5iEbfPST7TPFwDO01tI8dk1osLm6l4a17BWCaOMaBQlqxgTgYrtd09JJ9CvGoq5fo5j5TPxUc4Q==",
|
|
169
|
+
"win32-arm64v8": "sha512-b5Ver+uwOJhdOGqvZVM+qF2KLKcowcac/wKK5Fg0czqlSMqP/KxDF2kxw2eKXUJNgfqe4eDH1QG/yTg2pQSetQ==",
|
|
170
|
+
"win32-ia32": "sha512-h/SJ/Yfn0ce9H70vt1wS8rZ4PfHnguCCTsOGik7e6O/e2AlBQOM0mKsPIB9jSOquoCP8rP0qF6AOPOjXKnCk+w==",
|
|
171
|
+
"win32-x64": "sha512-p9qpdWdhZooPteib92Kk+qF1vvzcScxvOwdIP8muhgo/A8uDI4/mqXCpEbMBw6vjETKlS3qo2JUbVF6+0/lyWQ=="
|
|
170
172
|
},
|
|
171
173
|
"runtime": "napi",
|
|
172
|
-
"target":
|
|
174
|
+
"target": 7
|
|
173
175
|
},
|
|
174
176
|
"engines": {
|
|
175
|
-
"node": ">=
|
|
177
|
+
"node": ">=14.15.0"
|
|
176
178
|
},
|
|
177
179
|
"funding": {
|
|
178
180
|
"url": "https://opencollective.com/libvips"
|
|
179
181
|
},
|
|
180
182
|
"binary": {
|
|
181
183
|
"napi_versions": [
|
|
182
|
-
|
|
184
|
+
7
|
|
183
185
|
]
|
|
184
186
|
},
|
|
185
187
|
"semistandard": {
|