@revizly/sharp 0.35.0-revizly6 → 0.35.0-revizly8
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/install/build.js +2 -2
- package/lib/constructor.js +6 -1
- package/lib/index.d.ts +34 -38
- package/lib/input.js +3 -9
- package/lib/operation.js +4 -33
- package/lib/output.js +86 -8
- package/lib/resize.js +16 -0
- package/lib/sharp.js +5 -3
- package/lib/utility.js +1 -1
- package/package.json +12 -13
- package/src/binding.gyp +6 -3
- package/src/common.cc +62 -14
- package/src/common.h +12 -1
- package/src/metadata.cc +62 -5
- package/src/metadata.h +6 -1
- package/src/operations.cc +25 -8
- package/src/operations.h +1 -1
- package/src/pipeline.cc +46 -21
- package/src/pipeline.h +11 -1
- package/src/stats.cc +2 -3
- package/src/utilities.cc +4 -3
- package/install/check.js +0 -14
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions
|
|
|
8
8
|
|
|
9
9
|
It can be used with all JavaScript runtimes
|
|
10
10
|
that provide support for Node-API v9, including
|
|
11
|
-
Node.js (
|
|
11
|
+
Node.js (>= 20.9.0), Deno and Bun.
|
|
12
12
|
|
|
13
13
|
Resizing an image is typically 4x-5x faster than using the
|
|
14
14
|
quickest ImageMagick and GraphicsMagick settings
|
package/install/build.js
CHANGED
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
spawnRebuild,
|
|
11
11
|
} = require('../lib/libvips');
|
|
12
12
|
|
|
13
|
-
log('
|
|
13
|
+
log('Building from source');
|
|
14
14
|
log('See https://sharp.pixelplumbing.com/install#building-from-source');
|
|
15
15
|
|
|
16
16
|
try {
|
|
@@ -29,7 +29,7 @@ try {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
if (useGlobalLibvips(log)) {
|
|
32
|
-
log(`
|
|
32
|
+
log(`Found globally-installed libvips v${globalLibvipsVersion()}`);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const status = spawnRebuild();
|
package/lib/constructor.js
CHANGED
|
@@ -278,6 +278,7 @@ const Sharp = function (input, options) {
|
|
|
278
278
|
trimBackground: [],
|
|
279
279
|
trimThreshold: -1,
|
|
280
280
|
trimLineArt: false,
|
|
281
|
+
trimMargin: 0,
|
|
281
282
|
dilateWidth: 0,
|
|
282
283
|
erodeWidth: 0,
|
|
283
284
|
gamma: 0,
|
|
@@ -306,6 +307,7 @@ const Sharp = function (input, options) {
|
|
|
306
307
|
fileOut: '',
|
|
307
308
|
formatOut: 'input',
|
|
308
309
|
streamOut: false,
|
|
310
|
+
typedArrayOut: false,
|
|
309
311
|
keepMetadata: 0,
|
|
310
312
|
withMetadataOrientation: -1,
|
|
311
313
|
withMetadataDensity: 0,
|
|
@@ -313,6 +315,7 @@ const Sharp = function (input, options) {
|
|
|
313
315
|
withExif: {},
|
|
314
316
|
withExifMerge: true,
|
|
315
317
|
withXmp: '',
|
|
318
|
+
withGainMap: false,
|
|
316
319
|
resolveWithObject: false,
|
|
317
320
|
loop: -1,
|
|
318
321
|
delay: [],
|
|
@@ -348,6 +351,7 @@ const Sharp = function (input, options) {
|
|
|
348
351
|
webpEffort: 4,
|
|
349
352
|
webpMinSize: false,
|
|
350
353
|
webpMixed: false,
|
|
354
|
+
webpExact: false,
|
|
351
355
|
gifBitdepth: 8,
|
|
352
356
|
gifEffort: 7,
|
|
353
357
|
gifDither: 1,
|
|
@@ -362,7 +366,7 @@ const Sharp = function (input, options) {
|
|
|
362
366
|
tiffPredictor: 'horizontal',
|
|
363
367
|
tiffPyramid: false,
|
|
364
368
|
tiffMiniswhite: false,
|
|
365
|
-
tiffBitdepth:
|
|
369
|
+
tiffBitdepth: 0,
|
|
366
370
|
tiffTile: false,
|
|
367
371
|
tiffTileHeight: 256,
|
|
368
372
|
tiffTileWidth: 256,
|
|
@@ -375,6 +379,7 @@ const Sharp = function (input, options) {
|
|
|
375
379
|
heifEffort: 4,
|
|
376
380
|
heifChromaSubsampling: '4:4:4',
|
|
377
381
|
heifBitdepth: 8,
|
|
382
|
+
heifTune: 'ssim',
|
|
378
383
|
jxlDistance: 1,
|
|
379
384
|
jxlDecodingTier: 0,
|
|
380
385
|
jxlEffort: 7,
|
package/lib/index.d.ts
CHANGED
|
@@ -259,7 +259,6 @@ declare namespace sharp {
|
|
|
259
259
|
* Set the pipeline colourspace.
|
|
260
260
|
* The input image will be converted to the provided colourspace at the start of the pipeline.
|
|
261
261
|
* All operations will use this colourspace before converting to the output colourspace, as defined by toColourspace.
|
|
262
|
-
* This feature is experimental and has not yet been fully-tested with all operations.
|
|
263
262
|
*
|
|
264
263
|
* @param colourspace pipeline colourspace e.g. rgb16, scrgb, lab, grey16 ...
|
|
265
264
|
* @throws {Error} Invalid parameters
|
|
@@ -470,21 +469,6 @@ declare namespace sharp {
|
|
|
470
469
|
*/
|
|
471
470
|
sharpen(options?: SharpenOptions): Sharp;
|
|
472
471
|
|
|
473
|
-
/**
|
|
474
|
-
* Sharpen the image.
|
|
475
|
-
* When used without parameters, performs a fast, mild sharpen of the output image.
|
|
476
|
-
* When a sigma is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space.
|
|
477
|
-
* Fine-grained control over the level of sharpening in "flat" (m1) and "jagged" (m2) areas is available.
|
|
478
|
-
* @param sigma the sigma of the Gaussian mask, where sigma = 1 + radius / 2.
|
|
479
|
-
* @param flat the level of sharpening to apply to "flat" areas. (optional, default 1.0)
|
|
480
|
-
* @param jagged the level of sharpening to apply to "jagged" areas. (optional, default 2.0)
|
|
481
|
-
* @throws {Error} Invalid parameters
|
|
482
|
-
* @returns A sharp instance that can be used to chain operations
|
|
483
|
-
*
|
|
484
|
-
* @deprecated Use the object parameter `sharpen({sigma, m1, m2, x1, y2, y3})` instead
|
|
485
|
-
*/
|
|
486
|
-
sharpen(sigma?: number, flat?: number, jagged?: number): Sharp;
|
|
487
|
-
|
|
488
472
|
/**
|
|
489
473
|
* Apply median filter. When used without parameters the default window is 3x3.
|
|
490
474
|
* @param size square mask size: size x size (optional, default 3)
|
|
@@ -693,6 +677,13 @@ declare namespace sharp {
|
|
|
693
677
|
*/
|
|
694
678
|
toBuffer(options: { resolveWithObject: true }): Promise<{ data: Buffer; info: OutputInfo }>;
|
|
695
679
|
|
|
680
|
+
/**
|
|
681
|
+
* Write output to a Uint8Array backed by a transferable ArrayBuffer. JPEG, PNG, WebP, AVIF, TIFF, GIF and RAW output are supported.
|
|
682
|
+
* By default, the format will match the input image, except SVG input which becomes PNG output.
|
|
683
|
+
* @returns A promise that resolves with an object containing the Uint8Array data and an info object containing the output image format, size (bytes), width, height and channels
|
|
684
|
+
*/
|
|
685
|
+
toUint8Array(): Promise<{ data: Uint8Array; info: OutputInfo }>;
|
|
686
|
+
|
|
696
687
|
/**
|
|
697
688
|
* Keep all EXIF metadata from the input image in the output image.
|
|
698
689
|
* EXIF metadata is unsupported for TIFF output.
|
|
@@ -849,7 +840,7 @@ declare namespace sharp {
|
|
|
849
840
|
* @returns A sharp instance that can be used to chain operations
|
|
850
841
|
*/
|
|
851
842
|
toFormat(
|
|
852
|
-
format: keyof FormatEnum | AvailableFormatInfo,
|
|
843
|
+
format: keyof FormatEnum | AvailableFormatInfo | "avif",
|
|
853
844
|
options?:
|
|
854
845
|
| OutputOptions
|
|
855
846
|
| JpegOptions
|
|
@@ -903,7 +894,7 @@ declare namespace sharp {
|
|
|
903
894
|
* - sharp.gravity: north, northeast, east, southeast, south, southwest, west, northwest, center or centre.
|
|
904
895
|
* - sharp.strategy: cover only, dynamically crop using either the entropy or attention strategy. Some of these values are based on the object-position CSS property.
|
|
905
896
|
*
|
|
906
|
-
* The
|
|
897
|
+
* The strategy-based approach resizes so one dimension is at its target length then repeatedly ranks edge regions,
|
|
907
898
|
* discarding the edge with the lowest score based on the selected strategy.
|
|
908
899
|
* - entropy: focus on the region with the highest Shannon entropy.
|
|
909
900
|
* - attention: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones.
|
|
@@ -992,14 +983,6 @@ declare namespace sharp {
|
|
|
992
983
|
* 'none' (least), 'truncated', 'error' or 'warning' (most), highers level imply lower levels, invalid metadata will always abort. (optional, default 'warning')
|
|
993
984
|
*/
|
|
994
985
|
failOn?: FailOnOptions | undefined;
|
|
995
|
-
/**
|
|
996
|
-
* By default halt processing and raise an error when loading invalid images.
|
|
997
|
-
* Set this flag to false if you'd rather apply a "best effort" to decode images,
|
|
998
|
-
* even if the data is corrupt or invalid. (optional, default true)
|
|
999
|
-
*
|
|
1000
|
-
* @deprecated Use `failOn` instead
|
|
1001
|
-
*/
|
|
1002
|
-
failOnError?: boolean | undefined;
|
|
1003
986
|
/**
|
|
1004
987
|
* Do not process input images where the number of pixels (width x height) exceeds this limit.
|
|
1005
988
|
* Assumes image dimensions contained in the input metadata can be trusted.
|
|
@@ -1184,6 +1167,8 @@ declare namespace sharp {
|
|
|
1184
1167
|
|
|
1185
1168
|
type HeifCompression = 'av1' | 'hevc';
|
|
1186
1169
|
|
|
1170
|
+
type HeifTune = 'iq' | 'ssim' | 'psnr';
|
|
1171
|
+
|
|
1187
1172
|
type Unit = 'inch' | 'cm';
|
|
1188
1173
|
|
|
1189
1174
|
interface WriteableMetadata {
|
|
@@ -1277,6 +1262,8 @@ declare namespace sharp {
|
|
|
1277
1262
|
formatMagick?: string | undefined;
|
|
1278
1263
|
/** Array of keyword/text pairs representing PNG text blocks, if present. */
|
|
1279
1264
|
comments?: CommentsMetadata[] | undefined;
|
|
1265
|
+
/** HDR gain map, if present */
|
|
1266
|
+
gainMap?: GainMapMetadata | undefined;
|
|
1280
1267
|
}
|
|
1281
1268
|
|
|
1282
1269
|
interface LevelMetadata {
|
|
@@ -1289,16 +1276,21 @@ declare namespace sharp {
|
|
|
1289
1276
|
text: string;
|
|
1290
1277
|
}
|
|
1291
1278
|
|
|
1279
|
+
interface GainMapMetadata {
|
|
1280
|
+
/** JPEG image */
|
|
1281
|
+
image: Buffer;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1292
1284
|
interface Stats {
|
|
1293
1285
|
/** Array of channel statistics for each channel in the image. */
|
|
1294
1286
|
channels: ChannelStats[];
|
|
1295
1287
|
/** Value to identify if the image is opaque or transparent, based on the presence and use of alpha channel */
|
|
1296
1288
|
isOpaque: boolean;
|
|
1297
|
-
/** Histogram-based estimation of greyscale entropy, discarding alpha channel if any
|
|
1289
|
+
/** Histogram-based estimation of greyscale entropy, discarding alpha channel if any */
|
|
1298
1290
|
entropy: number;
|
|
1299
|
-
/** Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any
|
|
1291
|
+
/** Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any */
|
|
1300
1292
|
sharpness: number;
|
|
1301
|
-
/** Object containing most dominant sRGB colour based on a 4096-bin 3D histogram
|
|
1293
|
+
/** Object containing most dominant sRGB colour based on a 4096-bin 3D histogram */
|
|
1302
1294
|
dominant: { r: number; g: number; b: number };
|
|
1303
1295
|
}
|
|
1304
1296
|
|
|
@@ -1404,11 +1396,13 @@ declare namespace sharp {
|
|
|
1404
1396
|
/** Level of CPU effort to reduce file size, integer 0-6 (optional, default 4) */
|
|
1405
1397
|
effort?: number | undefined;
|
|
1406
1398
|
/** Prevent use of animation key frames to minimise file size (slow) (optional, default false) */
|
|
1407
|
-
minSize?: boolean;
|
|
1399
|
+
minSize?: boolean | undefined;
|
|
1408
1400
|
/** Allow mixture of lossy and lossless animation frames (slow) (optional, default false) */
|
|
1409
|
-
mixed?: boolean;
|
|
1401
|
+
mixed?: boolean | undefined;
|
|
1410
1402
|
/** Preset options: one of default, photo, picture, drawing, icon, text (optional, default 'default') */
|
|
1411
1403
|
preset?: keyof PresetEnum | undefined;
|
|
1404
|
+
/** Preserve the colour data in transparent pixels (optional, default false) */
|
|
1405
|
+
exact?: boolean | undefined;
|
|
1412
1406
|
}
|
|
1413
1407
|
|
|
1414
1408
|
interface AvifOptions extends OutputOptions {
|
|
@@ -1422,6 +1416,8 @@ declare namespace sharp {
|
|
|
1422
1416
|
chromaSubsampling?: string | undefined;
|
|
1423
1417
|
/** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
|
|
1424
1418
|
bitdepth?: 8 | 10 | 12 | undefined;
|
|
1419
|
+
/** Tune output for a quality metric, one of 'iq', 'ssim' or 'psnr' (optional, default 'iq') */
|
|
1420
|
+
tune?: HeifTune | undefined;
|
|
1425
1421
|
}
|
|
1426
1422
|
|
|
1427
1423
|
interface HeifOptions extends OutputOptions {
|
|
@@ -1437,6 +1433,8 @@ declare namespace sharp {
|
|
|
1437
1433
|
chromaSubsampling?: string | undefined;
|
|
1438
1434
|
/** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
|
|
1439
1435
|
bitdepth?: 8 | 10 | 12 | undefined;
|
|
1436
|
+
/** Tune output for a quality metric, one of 'ssim', 'psnr' or 'iq' (optional, default 'ssim') */
|
|
1437
|
+
tune?: HeifTune | undefined;
|
|
1440
1438
|
}
|
|
1441
1439
|
|
|
1442
1440
|
interface GifOptions extends OutputOptions, AnimationOptions {
|
|
@@ -1481,8 +1479,8 @@ declare namespace sharp {
|
|
|
1481
1479
|
xres?: number | undefined;
|
|
1482
1480
|
/** Vertical resolution in pixels/mm (optional, default 1.0) */
|
|
1483
1481
|
yres?: number | undefined;
|
|
1484
|
-
/** Reduce bitdepth to 1, 2 or 4 bit (optional
|
|
1485
|
-
bitdepth?: 1 | 2 | 4 |
|
|
1482
|
+
/** Reduce bitdepth to 1, 2 or 4 bit (optional) */
|
|
1483
|
+
bitdepth?: 1 | 2 | 4 | undefined;
|
|
1486
1484
|
/** Write 1-bit images as miniswhite (optional, default false) */
|
|
1487
1485
|
miniswhite?: boolean | undefined;
|
|
1488
1486
|
/** Resolution unit options: inch, cm (optional, default 'inch') */
|
|
@@ -1608,6 +1606,8 @@ declare namespace sharp {
|
|
|
1608
1606
|
threshold?: number | undefined;
|
|
1609
1607
|
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
|
1610
1608
|
lineArt?: boolean | undefined;
|
|
1609
|
+
/** Leave a margin around trimmed content, value is in pixels. (optional, default 0) */
|
|
1610
|
+
margin?: number | undefined;
|
|
1611
1611
|
}
|
|
1612
1612
|
|
|
1613
1613
|
interface RawOptions {
|
|
@@ -1913,16 +1913,13 @@ declare namespace sharp {
|
|
|
1913
1913
|
}
|
|
1914
1914
|
|
|
1915
1915
|
interface FormatEnum {
|
|
1916
|
-
avif: AvailableFormatInfo;
|
|
1917
1916
|
dcraw: AvailableFormatInfo;
|
|
1918
1917
|
dz: AvailableFormatInfo;
|
|
1919
1918
|
exr: AvailableFormatInfo;
|
|
1920
1919
|
fits: AvailableFormatInfo;
|
|
1921
1920
|
gif: AvailableFormatInfo;
|
|
1922
1921
|
heif: AvailableFormatInfo;
|
|
1923
|
-
input: AvailableFormatInfo;
|
|
1924
1922
|
jpeg: AvailableFormatInfo;
|
|
1925
|
-
jpg: AvailableFormatInfo;
|
|
1926
1923
|
jp2: AvailableFormatInfo;
|
|
1927
1924
|
jxl: AvailableFormatInfo;
|
|
1928
1925
|
magick: AvailableFormatInfo;
|
|
@@ -1934,8 +1931,7 @@ declare namespace sharp {
|
|
|
1934
1931
|
raw: AvailableFormatInfo;
|
|
1935
1932
|
svg: AvailableFormatInfo;
|
|
1936
1933
|
tiff: AvailableFormatInfo;
|
|
1937
|
-
|
|
1938
|
-
v: AvailableFormatInfo;
|
|
1934
|
+
vips: AvailableFormatInfo;
|
|
1939
1935
|
webp: AvailableFormatInfo;
|
|
1940
1936
|
}
|
|
1941
1937
|
|
package/lib/input.js
CHANGED
|
@@ -30,7 +30,7 @@ const inputStreamParameters = [
|
|
|
30
30
|
// Format-specific
|
|
31
31
|
'jp2', 'openSlide', 'pdf', 'raw', 'svg', 'tiff',
|
|
32
32
|
// Deprecated
|
|
33
|
-
'
|
|
33
|
+
'openSlideLevel', 'pdfBackground', 'tiffSubifd'
|
|
34
34
|
];
|
|
35
35
|
|
|
36
36
|
/**
|
|
@@ -106,14 +106,6 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
106
106
|
}`);
|
|
107
107
|
}
|
|
108
108
|
if (is.object(inputOptions)) {
|
|
109
|
-
// Deprecated: failOnError
|
|
110
|
-
if (is.defined(inputOptions.failOnError)) {
|
|
111
|
-
if (is.bool(inputOptions.failOnError)) {
|
|
112
|
-
inputDescriptor.failOn = inputOptions.failOnError ? 'warning' : 'none';
|
|
113
|
-
} else {
|
|
114
|
-
throw is.invalidParameterError('failOnError', 'boolean', inputOptions.failOnError);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
109
|
// failOn
|
|
118
110
|
if (is.defined(inputOptions.failOn)) {
|
|
119
111
|
if (is.string(inputOptions.failOn) && is.inArray(inputOptions.failOn, ['none', 'truncated', 'error', 'warning'])) {
|
|
@@ -575,6 +567,7 @@ function _isStreamInput () {
|
|
|
575
567
|
* A `Promise` is returned when `callback` is not provided.
|
|
576
568
|
*
|
|
577
569
|
* - `format`: Name of decoder used to parse image e.g. `jpeg`, `png`, `webp`, `gif`, `svg`, `heif`, `tiff`
|
|
570
|
+
* - `mediaType`: Media Type (MIME Type) e.g. `image/jpeg`, `image/png`, `image/svg+xml`, `image/avif`
|
|
578
571
|
* - `size`: Total size of image in bytes, for Stream and Buffer input only
|
|
579
572
|
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
|
|
580
573
|
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
|
|
@@ -607,6 +600,7 @@ function _isStreamInput () {
|
|
|
607
600
|
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
|
608
601
|
* - `formatMagick`: String containing format for images loaded via *magick
|
|
609
602
|
* - `comments`: Array of keyword/text pairs representing PNG text blocks, if present.
|
|
603
|
+
* - `gainMap.image`: HDR gain map, if present, as compressed JPEG image.
|
|
610
604
|
*
|
|
611
605
|
* @example
|
|
612
606
|
* const metadata = await sharp(input).metadata();
|
package/lib/operation.js
CHANGED
|
@@ -259,45 +259,18 @@ function affine (matrix, options) {
|
|
|
259
259
|
* })
|
|
260
260
|
* .toBuffer();
|
|
261
261
|
*
|
|
262
|
-
* @param {Object
|
|
262
|
+
* @param {Object} [options] - if present, is an Object with attributes
|
|
263
263
|
* @param {number} [options.sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`, between 0.000001 and 10
|
|
264
264
|
* @param {number} [options.m1=1.0] - the level of sharpening to apply to "flat" areas, between 0 and 1000000
|
|
265
265
|
* @param {number} [options.m2=2.0] - the level of sharpening to apply to "jagged" areas, between 0 and 1000000
|
|
266
266
|
* @param {number} [options.x1=2.0] - threshold between "flat" and "jagged", between 0 and 1000000
|
|
267
267
|
* @param {number} [options.y2=10.0] - maximum amount of brightening, between 0 and 1000000
|
|
268
268
|
* @param {number} [options.y3=20.0] - maximum amount of darkening, between 0 and 1000000
|
|
269
|
-
* @param {number} [flat] - (deprecated) see `options.m1`.
|
|
270
|
-
* @param {number} [jagged] - (deprecated) see `options.m2`.
|
|
271
269
|
* @returns {Sharp}
|
|
272
270
|
* @throws {Error} Invalid parameters
|
|
273
271
|
*/
|
|
274
|
-
function sharpen (options
|
|
275
|
-
if (
|
|
276
|
-
// No arguments: default to mild sharpen
|
|
277
|
-
this.options.sharpenSigma = -1;
|
|
278
|
-
} else if (is.bool(options)) {
|
|
279
|
-
// Deprecated boolean argument: apply mild sharpen?
|
|
280
|
-
this.options.sharpenSigma = options ? -1 : 0;
|
|
281
|
-
} else if (is.number(options) && is.inRange(options, 0.01, 10000)) {
|
|
282
|
-
// Deprecated numeric argument: specific sigma
|
|
283
|
-
this.options.sharpenSigma = options;
|
|
284
|
-
// Deprecated control over flat areas
|
|
285
|
-
if (is.defined(flat)) {
|
|
286
|
-
if (is.number(flat) && is.inRange(flat, 0, 10000)) {
|
|
287
|
-
this.options.sharpenM1 = flat;
|
|
288
|
-
} else {
|
|
289
|
-
throw is.invalidParameterError('flat', 'number between 0 and 10000', flat);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
// Deprecated control over jagged areas
|
|
293
|
-
if (is.defined(jagged)) {
|
|
294
|
-
if (is.number(jagged) && is.inRange(jagged, 0, 10000)) {
|
|
295
|
-
this.options.sharpenM2 = jagged;
|
|
296
|
-
} else {
|
|
297
|
-
throw is.invalidParameterError('jagged', 'number between 0 and 10000', jagged);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
} else if (is.plainObject(options)) {
|
|
272
|
+
function sharpen (options) {
|
|
273
|
+
if (is.plainObject(options)) {
|
|
301
274
|
if (is.number(options.sigma) && is.inRange(options.sigma, 0.000001, 10)) {
|
|
302
275
|
this.options.sharpenSigma = options.sigma;
|
|
303
276
|
} else {
|
|
@@ -339,7 +312,7 @@ function sharpen (options, flat, jagged) {
|
|
|
339
312
|
}
|
|
340
313
|
}
|
|
341
314
|
} else {
|
|
342
|
-
|
|
315
|
+
this.options.sharpenSigma = -1;
|
|
343
316
|
}
|
|
344
317
|
return this;
|
|
345
318
|
}
|
|
@@ -510,8 +483,6 @@ function flatten (options) {
|
|
|
510
483
|
*
|
|
511
484
|
* Existing alpha channel values for non-white pixels remain unchanged.
|
|
512
485
|
*
|
|
513
|
-
* This feature is experimental and the API may change.
|
|
514
|
-
*
|
|
515
486
|
* @since 0.32.1
|
|
516
487
|
*
|
|
517
488
|
* @example
|
package/lib/output.js
CHANGED
|
@@ -76,7 +76,7 @@ function toFile (fileOut, callback) {
|
|
|
76
76
|
err = new Error('Missing output file path');
|
|
77
77
|
} else if (is.string(this.options.input.file) && path.resolve(this.options.input.file) === path.resolve(fileOut)) {
|
|
78
78
|
err = new Error('Cannot use same file for input and output');
|
|
79
|
-
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.
|
|
79
|
+
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2.output.file) {
|
|
80
80
|
err = errJp2Save();
|
|
81
81
|
}
|
|
82
82
|
if (err) {
|
|
@@ -164,6 +164,41 @@ function toBuffer (options, callback) {
|
|
|
164
164
|
return this._pipeline(is.fn(options) ? options : callback, stack);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Write output to a `Uint8Array` backed by a transferable `ArrayBuffer`.
|
|
169
|
+
* JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
|
170
|
+
*
|
|
171
|
+
* Use {@link #toformat toFormat} or one of the format-specific functions such as {@link #jpeg jpeg}, {@link #png png} etc. to set the output format.
|
|
172
|
+
*
|
|
173
|
+
* If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
|
174
|
+
*
|
|
175
|
+
* By default all metadata will be removed, which includes EXIF-based orientation.
|
|
176
|
+
* See {@link #keepexif keepExif} and similar methods for control over this.
|
|
177
|
+
*
|
|
178
|
+
* Resolves with an `Object` containing:
|
|
179
|
+
* - `data` is the output image as a `Uint8Array` backed by a transferable `ArrayBuffer`.
|
|
180
|
+
* - `info` contains properties relating to the output image such as `width` and `height`.
|
|
181
|
+
*
|
|
182
|
+
* @since v0.35.0
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* const { data, info } = await sharp(input).toUint8Array();
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* const { data } = await sharp(input)
|
|
189
|
+
* .avif()
|
|
190
|
+
* .toUint8Array();
|
|
191
|
+
* const base64String = data.toBase64();
|
|
192
|
+
*
|
|
193
|
+
* @returns {Promise<{ data: Uint8Array, info: Object }>}
|
|
194
|
+
*/
|
|
195
|
+
function toUint8Array () {
|
|
196
|
+
this.options.resolveWithObject = true;
|
|
197
|
+
this.options.typedArrayOut = true;
|
|
198
|
+
const stack = Error();
|
|
199
|
+
return this._pipeline(null, stack);
|
|
200
|
+
}
|
|
201
|
+
|
|
167
202
|
/**
|
|
168
203
|
* Keep all EXIF metadata from the input image in the output image.
|
|
169
204
|
*
|
|
@@ -319,6 +354,30 @@ function withIccProfile (icc, options) {
|
|
|
319
354
|
return this;
|
|
320
355
|
}
|
|
321
356
|
|
|
357
|
+
/**
|
|
358
|
+
* If the input contains gain map metadata, use it to convert the main image to HDR (High Dynamic Range) before further processing.
|
|
359
|
+
* The input gain map is discarded.
|
|
360
|
+
*
|
|
361
|
+
* If the output is JPEG, generate and attach a new ISO 21496-1 gain map.
|
|
362
|
+
* JPEG output options other than `quality` are ignored.
|
|
363
|
+
*
|
|
364
|
+
* This feature is experimental and the API may change.
|
|
365
|
+
*
|
|
366
|
+
* @since 0.35.0
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* const outputWithGainMap = await sharp(inputWithGainMap)
|
|
370
|
+
* .withGainMap()
|
|
371
|
+
* .toBuffer();
|
|
372
|
+
*
|
|
373
|
+
* @returns {Sharp}
|
|
374
|
+
*/
|
|
375
|
+
function withGainMap() {
|
|
376
|
+
this.options.withGainMap = true;
|
|
377
|
+
this.options.colourspace = 'scrgb';
|
|
378
|
+
return this;
|
|
379
|
+
}
|
|
380
|
+
|
|
322
381
|
/**
|
|
323
382
|
* Keep XMP metadata from the input image in the output image.
|
|
324
383
|
*
|
|
@@ -690,6 +749,7 @@ function png (options) {
|
|
|
690
749
|
* @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
|
|
691
750
|
* @param {boolean} [options.minSize=false] - prevent use of animation key frames to minimise file size (slow)
|
|
692
751
|
* @param {boolean} [options.mixed=false] - allow mixture of lossy and lossless animation frames (slow)
|
|
752
|
+
* @param {boolean} [options.exact=false] - preserve the colour data in transparent pixels
|
|
693
753
|
* @param {boolean} [options.force=true] - force WebP output, otherwise attempt to use input format
|
|
694
754
|
* @returns {Sharp}
|
|
695
755
|
* @throws {Error} Invalid options
|
|
@@ -742,6 +802,9 @@ function webp (options) {
|
|
|
742
802
|
if (is.defined(options.mixed)) {
|
|
743
803
|
this._setBooleanOption('webpMixed', options.mixed);
|
|
744
804
|
}
|
|
805
|
+
if (is.defined(options.exact)) {
|
|
806
|
+
this._setBooleanOption('webpExact', options.exact);
|
|
807
|
+
}
|
|
745
808
|
}
|
|
746
809
|
trySetAnimationOptions(options, this.options);
|
|
747
810
|
return this._updateFormatOut('webp', options);
|
|
@@ -887,7 +950,7 @@ function gif (options) {
|
|
|
887
950
|
*/
|
|
888
951
|
function jp2 (options) {
|
|
889
952
|
/* node:coverage ignore next 41 */
|
|
890
|
-
if (!this.constructor.format.
|
|
953
|
+
if (!this.constructor.format.jp2.output.buffer) {
|
|
891
954
|
throw errJp2Save();
|
|
892
955
|
}
|
|
893
956
|
if (is.object(options)) {
|
|
@@ -992,7 +1055,7 @@ function trySetAnimationOptions (source, target) {
|
|
|
992
1055
|
* @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm
|
|
993
1056
|
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
|
994
1057
|
* @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
|
|
995
|
-
* @param {number} [options.bitdepth=
|
|
1058
|
+
* @param {number} [options.bitdepth=0] - reduce bitdepth to 1, 2 or 4 bit
|
|
996
1059
|
* @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
|
|
997
1060
|
* @returns {Sharp}
|
|
998
1061
|
* @throws {Error} Invalid options
|
|
@@ -1007,10 +1070,10 @@ function tiff (options) {
|
|
|
1007
1070
|
}
|
|
1008
1071
|
}
|
|
1009
1072
|
if (is.defined(options.bitdepth)) {
|
|
1010
|
-
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4
|
|
1073
|
+
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4])) {
|
|
1011
1074
|
this.options.tiffBitdepth = options.bitdepth;
|
|
1012
1075
|
} else {
|
|
1013
|
-
throw is.invalidParameterError('bitdepth', '1, 2
|
|
1076
|
+
throw is.invalidParameterError('bitdepth', '1, 2 or 4', options.bitdepth);
|
|
1014
1077
|
}
|
|
1015
1078
|
}
|
|
1016
1079
|
// tiling
|
|
@@ -1092,8 +1155,7 @@ function tiff (options) {
|
|
|
1092
1155
|
* AVIF image sequences are not supported.
|
|
1093
1156
|
* Prebuilt binaries support a bitdepth of 8 only.
|
|
1094
1157
|
*
|
|
1095
|
-
*
|
|
1096
|
-
* and requires a CPU with ARM64v8.4 or later.
|
|
1158
|
+
* When using Windows ARM64, this feature requires a CPU with ARM64v8.4 or later.
|
|
1097
1159
|
*
|
|
1098
1160
|
* @example
|
|
1099
1161
|
* const data = await sharp(input)
|
|
@@ -1113,11 +1175,13 @@ function tiff (options) {
|
|
|
1113
1175
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1114
1176
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1115
1177
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1178
|
+
* @param {string} [options.tune='iq'] - tune output for a quality metric, one of 'iq' (default), 'ssim' (default when lossless) or 'psnr'
|
|
1116
1179
|
* @returns {Sharp}
|
|
1117
1180
|
* @throws {Error} Invalid options
|
|
1118
1181
|
*/
|
|
1119
1182
|
function avif (options) {
|
|
1120
|
-
|
|
1183
|
+
const tune = is.object(options) && is.defined(options.tune) ? options.tune : 'iq';
|
|
1184
|
+
return this.heif({ ...options, compression: 'av1', tune });
|
|
1121
1185
|
}
|
|
1122
1186
|
|
|
1123
1187
|
/**
|
|
@@ -1140,6 +1204,7 @@ function avif (options) {
|
|
|
1140
1204
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1141
1205
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1142
1206
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1207
|
+
* @param {string} [options.tune='ssim'] - tune output for a quality metric, one of 'ssim' (default), 'psnr' or 'iq'
|
|
1143
1208
|
* @returns {Sharp}
|
|
1144
1209
|
* @throws {Error} Invalid options
|
|
1145
1210
|
*/
|
|
@@ -1188,6 +1253,17 @@ function heif (options) {
|
|
|
1188
1253
|
throw is.invalidParameterError('bitdepth', '8, 10 or 12', options.bitdepth);
|
|
1189
1254
|
}
|
|
1190
1255
|
}
|
|
1256
|
+
if (is.defined(options.tune)) {
|
|
1257
|
+
if (is.string(options.tune) && is.inArray(options.tune, ['iq', 'ssim', 'psnr'])) {
|
|
1258
|
+
if (this.options.heifLossless && options.tune === 'iq') {
|
|
1259
|
+
this.options.heifTune = 'ssim';
|
|
1260
|
+
} else {
|
|
1261
|
+
this.options.heifTune = options.tune;
|
|
1262
|
+
}
|
|
1263
|
+
} else {
|
|
1264
|
+
throw is.invalidParameterError('tune', 'one of: psnr, ssim, iq', options.tune);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1191
1267
|
} else {
|
|
1192
1268
|
throw is.invalidParameterError('options', 'Object', options);
|
|
1193
1269
|
}
|
|
@@ -1635,11 +1711,13 @@ module.exports = (Sharp) => {
|
|
|
1635
1711
|
// Public
|
|
1636
1712
|
toFile,
|
|
1637
1713
|
toBuffer,
|
|
1714
|
+
toUint8Array,
|
|
1638
1715
|
keepExif,
|
|
1639
1716
|
withExif,
|
|
1640
1717
|
withExifMerge,
|
|
1641
1718
|
keepIccProfile,
|
|
1642
1719
|
withIccProfile,
|
|
1720
|
+
withGainMap,
|
|
1643
1721
|
keepXmp,
|
|
1644
1722
|
withXmp,
|
|
1645
1723
|
keepMetadata,
|
package/lib/resize.js
CHANGED
|
@@ -540,10 +540,19 @@ function extract (options) {
|
|
|
540
540
|
* })
|
|
541
541
|
* .toBuffer();
|
|
542
542
|
*
|
|
543
|
+
* @example
|
|
544
|
+
* // Trim image leaving (up to) a 10 pixel margin around the trimmed content.
|
|
545
|
+
* const output = await sharp(input)
|
|
546
|
+
* .trim({
|
|
547
|
+
* margin: 10
|
|
548
|
+
* })
|
|
549
|
+
* .toBuffer();
|
|
550
|
+
*
|
|
543
551
|
* @param {Object} [options]
|
|
544
552
|
* @param {string|Object} [options.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.
|
|
545
553
|
* @param {number} [options.threshold=10] - Allowed difference from the above colour, a positive number.
|
|
546
554
|
* @param {boolean} [options.lineArt=false] - Does the input more closely resemble line art (e.g. vector) rather than being photographic?
|
|
555
|
+
* @param {number} [options.margin=0] - Leave a margin around trimmed content, value is in pixels.
|
|
547
556
|
* @returns {Sharp}
|
|
548
557
|
* @throws {Error} Invalid parameters
|
|
549
558
|
*/
|
|
@@ -564,6 +573,13 @@ function trim (options) {
|
|
|
564
573
|
if (is.defined(options.lineArt)) {
|
|
565
574
|
this._setBooleanOption('trimLineArt', options.lineArt);
|
|
566
575
|
}
|
|
576
|
+
if (is.defined(options.margin)) {
|
|
577
|
+
if (is.integer(options.margin) && options.margin >= 0) {
|
|
578
|
+
this.options.trimMargin = options.margin;
|
|
579
|
+
} else {
|
|
580
|
+
throw is.invalidParameterError('margin', 'positive integer', options.margin);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
567
583
|
} else {
|
|
568
584
|
throw is.invalidParameterError('trim', 'object', options);
|
|
569
585
|
}
|
package/lib/sharp.js
CHANGED
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
const { familySync, versionSync } = require('detect-libc');
|
|
9
9
|
|
|
10
|
+
const { version } = require('../package.json');
|
|
10
11
|
const { runtimePlatformArch, isUnsupportedNodeRuntime, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
|
|
11
12
|
const runtimePlatform = runtimePlatformArch();
|
|
12
13
|
|
|
13
14
|
const paths = [
|
|
14
|
-
`../src/build/Release/sharp-${runtimePlatform}.node`,
|
|
15
|
-
|
|
16
|
-
`@revizly/
|
|
15
|
+
`../src/build/Release/sharp-${runtimePlatform}-${version}.node`,
|
|
16
|
+
`../src/build/Release/sharp-wasm32-${version}.node`,
|
|
17
|
+
`@revizly/harp-${runtimePlatform}/sharp.node`,
|
|
17
18
|
'@revizly/sharp-wasm32/sharp.node'
|
|
18
19
|
];
|
|
19
20
|
|
|
@@ -72,6 +73,7 @@ if (sharp) {
|
|
|
72
73
|
} else {
|
|
73
74
|
help.push(
|
|
74
75
|
`- Manually install libvips >= ${minimumLibvipsVersion}`,
|
|
76
|
+
' See https://sharp.pixelplumbing.com/install#building-from-source',
|
|
75
77
|
'- Add experimental WebAssembly-based dependencies:',
|
|
76
78
|
' npm install --cpu=wasm32 sharp',
|
|
77
79
|
' npm install @revizly/sharp-wasm32'
|
package/lib/utility.js
CHANGED
|
@@ -24,7 +24,7 @@ const format = sharp.format();
|
|
|
24
24
|
format.heif.output.alias = ['avif', 'heic'];
|
|
25
25
|
format.jpeg.output.alias = ['jpe', 'jpg'];
|
|
26
26
|
format.tiff.output.alias = ['tif'];
|
|
27
|
-
format.
|
|
27
|
+
format.jp2.output.alias = ['j2c', 'j2k', 'jp2', 'jpx'];
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* An Object containing the available interpolators and their proper values
|