sharp 0.33.0-alpha.9 → 0.33.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 +6 -2
- package/lib/colour.js +4 -6
- package/lib/constructor.js +13 -7
- package/lib/index.d.ts +76 -13
- package/lib/libvips.js +25 -7
- package/lib/output.js +185 -49
- package/lib/resize.js +42 -45
- package/lib/sharp.js +70 -53
- package/lib/utility.js +10 -4
- package/package.json +36 -23
- package/src/binding.gyp +33 -23
- package/src/common.cc +48 -1
- package/src/common.h +18 -3
- package/src/metadata.cc +3 -3
- package/src/operations.cc +35 -18
- package/src/operations.h +3 -3
- package/src/pipeline.cc +64 -54
- package/src/pipeline.h +13 -9
- package/src/stats.cc +3 -3
- package/src/utilities.cc +5 -0
package/README.md
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
|
4
4
|
|
|
5
|
-
The typical use case for this high speed Node
|
|
5
|
+
The typical use case for this high speed Node-API module
|
|
6
6
|
is to convert large images in common formats to
|
|
7
7
|
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
|
|
8
8
|
|
|
9
|
+
It can be used with all JavaScript runtimes
|
|
10
|
+
that provide support for Node-API v9, including
|
|
11
|
+
Node.js >= 18.17.0, Deno and Bun.
|
|
12
|
+
|
|
9
13
|
Resizing an image is typically 4x-5x faster than using the
|
|
10
14
|
quickest ImageMagick and GraphicsMagick settings
|
|
11
15
|
due to its use of [libvips](https://github.com/libvips/libvips).
|
|
@@ -16,7 +20,7 @@ Lanczos resampling ensures quality is not sacrificed for speed.
|
|
|
16
20
|
As well as image resizing, operations such as
|
|
17
21
|
rotation, extraction, compositing and gamma correction are available.
|
|
18
22
|
|
|
19
|
-
Most modern macOS, Windows and Linux systems
|
|
23
|
+
Most modern macOS, Windows and Linux systems
|
|
20
24
|
do not require any additional install or runtime dependencies.
|
|
21
25
|
|
|
22
26
|
## Documentation
|
package/lib/colour.js
CHANGED
|
@@ -19,7 +19,7 @@ const colourspace = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Tint the image using the provided
|
|
22
|
+
* Tint the image using the provided colour.
|
|
23
23
|
* An alpha channel may be present and will be unchanged by the operation.
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
@@ -27,14 +27,12 @@ const colourspace = {
|
|
|
27
27
|
* .tint({ r: 255, g: 240, b: 16 })
|
|
28
28
|
* .toBuffer();
|
|
29
29
|
*
|
|
30
|
-
* @param {string|Object}
|
|
30
|
+
* @param {string|Object} tint - Parsed by the [color](https://www.npmjs.org/package/color) module.
|
|
31
31
|
* @returns {Sharp}
|
|
32
32
|
* @throws {Error} Invalid parameter
|
|
33
33
|
*/
|
|
34
|
-
function tint (
|
|
35
|
-
|
|
36
|
-
this.options.tintA = colour.a();
|
|
37
|
-
this.options.tintB = colour.b();
|
|
34
|
+
function tint (tint) {
|
|
35
|
+
this._setBackgroundColourOption('tint', tint);
|
|
38
36
|
return this;
|
|
39
37
|
}
|
|
40
38
|
|
package/lib/constructor.js
CHANGED
|
@@ -22,6 +22,10 @@ const debuglog = util.debuglog('sharp');
|
|
|
22
22
|
*
|
|
23
23
|
* Implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.
|
|
24
24
|
*
|
|
25
|
+
* When loading more than one page/frame of an animated image,
|
|
26
|
+
* these are combined as a vertically-stacked "toilet roll" image
|
|
27
|
+
* where the overall height is the `pageHeight` multiplied by the number of `pages`.
|
|
28
|
+
*
|
|
25
29
|
* @constructs Sharp
|
|
26
30
|
*
|
|
27
31
|
* @emits Sharp#info
|
|
@@ -121,7 +125,7 @@ const debuglog = util.debuglog('sharp');
|
|
|
121
125
|
* a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
|
122
126
|
* JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
|
123
127
|
* @param {Object} [options] - if present, is an Object with optional attributes.
|
|
124
|
-
* @param {string} [options.failOn='warning'] -
|
|
128
|
+
* @param {string} [options.failOn='warning'] - When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort.
|
|
125
129
|
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
|
|
126
130
|
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
|
127
131
|
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
|
|
@@ -212,8 +216,7 @@ const Sharp = function (input, options) {
|
|
|
212
216
|
kernel: 'lanczos3',
|
|
213
217
|
fastShrinkOnLoad: true,
|
|
214
218
|
// operations
|
|
215
|
-
|
|
216
|
-
tintB: 128,
|
|
219
|
+
tint: [-1, 0, 0, 0],
|
|
217
220
|
flatten: false,
|
|
218
221
|
flattenBackground: [0, 0, 0],
|
|
219
222
|
unflatten: false,
|
|
@@ -230,7 +233,8 @@ const Sharp = function (input, options) {
|
|
|
230
233
|
threshold: 0,
|
|
231
234
|
thresholdGrayscale: true,
|
|
232
235
|
trimBackground: [],
|
|
233
|
-
trimThreshold:
|
|
236
|
+
trimThreshold: -1,
|
|
237
|
+
trimLineArt: false,
|
|
234
238
|
gamma: 0,
|
|
235
239
|
gammaOut: 0,
|
|
236
240
|
greyscale: false,
|
|
@@ -257,11 +261,12 @@ const Sharp = function (input, options) {
|
|
|
257
261
|
fileOut: '',
|
|
258
262
|
formatOut: 'input',
|
|
259
263
|
streamOut: false,
|
|
260
|
-
|
|
264
|
+
keepMetadata: 0,
|
|
261
265
|
withMetadataOrientation: -1,
|
|
262
266
|
withMetadataDensity: 0,
|
|
263
|
-
|
|
264
|
-
|
|
267
|
+
withIccProfile: '',
|
|
268
|
+
withExif: {},
|
|
269
|
+
withExifMerge: true,
|
|
265
270
|
resolveWithObject: false,
|
|
266
271
|
// output format
|
|
267
272
|
jpegQuality: 80,
|
|
@@ -305,6 +310,7 @@ const Sharp = function (input, options) {
|
|
|
305
310
|
tiffCompression: 'jpeg',
|
|
306
311
|
tiffPredictor: 'horizontal',
|
|
307
312
|
tiffPyramid: false,
|
|
313
|
+
tiffMiniswhite: false,
|
|
308
314
|
tiffBitdepth: 8,
|
|
309
315
|
tiffTile: false,
|
|
310
316
|
tiffTileHeight: 256,
|
package/lib/index.d.ts
CHANGED
|
@@ -239,12 +239,12 @@ declare namespace sharp {
|
|
|
239
239
|
//#region Color functions
|
|
240
240
|
|
|
241
241
|
/**
|
|
242
|
-
* Tint the image using the provided
|
|
242
|
+
* Tint the image using the provided colour.
|
|
243
243
|
* An alpha channel may be present and will be unchanged by the operation.
|
|
244
|
-
* @param
|
|
244
|
+
* @param tint Parsed by the color module.
|
|
245
245
|
* @returns A sharp instance that can be used to chain operations
|
|
246
246
|
*/
|
|
247
|
-
tint(
|
|
247
|
+
tint(tint: Color): Sharp;
|
|
248
248
|
|
|
249
249
|
/**
|
|
250
250
|
* Convert to 8-bit greyscale; 256 shades of grey.
|
|
@@ -633,6 +633,43 @@ declare namespace sharp {
|
|
|
633
633
|
*/
|
|
634
634
|
toBuffer(options: { resolveWithObject: true }): Promise<{ data: Buffer; info: OutputInfo }>;
|
|
635
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Keep all EXIF metadata from the input image in the output image.
|
|
638
|
+
* EXIF metadata is unsupported for TIFF output.
|
|
639
|
+
* @returns A sharp instance that can be used to chain operations
|
|
640
|
+
*/
|
|
641
|
+
keepExif(): Sharp;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Set EXIF metadata in the output image, ignoring any EXIF in the input image.
|
|
645
|
+
* @param {Exif} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
|
646
|
+
* @returns A sharp instance that can be used to chain operations
|
|
647
|
+
* @throws {Error} Invalid parameters
|
|
648
|
+
*/
|
|
649
|
+
withExif(exif: Exif): Sharp;
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Update EXIF metadata from the input image in the output image.
|
|
653
|
+
* @param {Exif} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
|
654
|
+
* @returns A sharp instance that can be used to chain operations
|
|
655
|
+
* @throws {Error} Invalid parameters
|
|
656
|
+
*/
|
|
657
|
+
withExifMerge(exif: Exif): Sharp;
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Keep ICC profile from the input image in the output image where possible.
|
|
661
|
+
* @returns A sharp instance that can be used to chain operations
|
|
662
|
+
*/
|
|
663
|
+
keepIccProfile(): Sharp;
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Transform using an ICC profile and attach to the output image.
|
|
667
|
+
* @param {string} icc - Absolute filesystem path to output ICC profile or built-in profile name (srgb, p3, cmyk).
|
|
668
|
+
* @returns A sharp instance that can be used to chain operations
|
|
669
|
+
* @throws {Error} Invalid parameters
|
|
670
|
+
*/
|
|
671
|
+
withIccProfile(icc: string, options?: WithIccProfileOptions): Sharp;
|
|
672
|
+
|
|
636
673
|
/**
|
|
637
674
|
* Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
|
|
638
675
|
* The default behaviour, when withMetadata is not used, is to strip all metadata and convert to the device-independent sRGB colour space.
|
|
@@ -640,7 +677,7 @@ declare namespace sharp {
|
|
|
640
677
|
* @param withMetadata
|
|
641
678
|
* @throws {Error} Invalid parameters.
|
|
642
679
|
*/
|
|
643
|
-
withMetadata(withMetadata?:
|
|
680
|
+
withMetadata(withMetadata?: WriteableMetadata): Sharp;
|
|
644
681
|
|
|
645
682
|
/**
|
|
646
683
|
* Use these JPEG options for output image.
|
|
@@ -847,11 +884,11 @@ declare namespace sharp {
|
|
|
847
884
|
* Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
|
848
885
|
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
|
849
886
|
* The info response Object will contain trimOffsetLeft and trimOffsetTop properties.
|
|
850
|
-
* @param
|
|
887
|
+
* @param options trim options
|
|
851
888
|
* @throws {Error} Invalid parameters
|
|
852
889
|
* @returns A sharp instance that can be used to chain operations
|
|
853
890
|
*/
|
|
854
|
-
trim(
|
|
891
|
+
trim(options?: TrimOptions): Sharp;
|
|
855
892
|
|
|
856
893
|
//#endregion
|
|
857
894
|
}
|
|
@@ -978,15 +1015,32 @@ declare namespace sharp {
|
|
|
978
1015
|
wrap?: TextWrap;
|
|
979
1016
|
}
|
|
980
1017
|
|
|
1018
|
+
interface ExifDir {
|
|
1019
|
+
[k: string]: string;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
interface Exif {
|
|
1023
|
+
'IFD0'?: ExifDir;
|
|
1024
|
+
'IFD1'?: ExifDir;
|
|
1025
|
+
'IFD2'?: ExifDir;
|
|
1026
|
+
'IFD3'?: ExifDir;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
981
1029
|
interface WriteableMetadata {
|
|
1030
|
+
/** Number of pixels per inch (DPI) */
|
|
1031
|
+
density?: number | undefined;
|
|
982
1032
|
/** Value between 1 and 8, used to update the EXIF Orientation tag. */
|
|
983
1033
|
orientation?: number | undefined;
|
|
984
|
-
/**
|
|
1034
|
+
/**
|
|
1035
|
+
* Filesystem path to output ICC profile, defaults to sRGB.
|
|
1036
|
+
* @deprecated Use `withIccProfile()` instead.
|
|
1037
|
+
*/
|
|
985
1038
|
icc?: string | undefined;
|
|
986
|
-
/**
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1039
|
+
/**
|
|
1040
|
+
* Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
|
1041
|
+
* @deprecated Use `withExif()` or `withExifMerge()` instead.
|
|
1042
|
+
*/
|
|
1043
|
+
exif?: Exif | undefined;
|
|
990
1044
|
}
|
|
991
1045
|
|
|
992
1046
|
interface Metadata {
|
|
@@ -1096,6 +1150,11 @@ declare namespace sharp {
|
|
|
1096
1150
|
force?: boolean | undefined;
|
|
1097
1151
|
}
|
|
1098
1152
|
|
|
1153
|
+
interface WithIccProfileOptions {
|
|
1154
|
+
/** Should the ICC profile be included in the output image metadata? (optional, default true) */
|
|
1155
|
+
attach?: boolean | undefined;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1099
1158
|
interface JpegOptions extends OutputOptions {
|
|
1100
1159
|
/** Quality, integer 1-100 (optional, default 80) */
|
|
1101
1160
|
quality?: number | undefined;
|
|
@@ -1234,6 +1293,8 @@ declare namespace sharp {
|
|
|
1234
1293
|
yres?: number | undefined;
|
|
1235
1294
|
/** Reduce bitdepth to 1, 2 or 4 bit (optional, default 8) */
|
|
1236
1295
|
bitdepth?: 1 | 2 | 4 | 8 | undefined;
|
|
1296
|
+
/** Write 1-bit images as miniswhite (optional, default false) */
|
|
1297
|
+
miniswhite?: boolean | undefined;
|
|
1237
1298
|
/** Resolution unit options: inch, cm (optional, default 'inch') */
|
|
1238
1299
|
resolutionUnit?: 'inch' | 'cm' | undefined;
|
|
1239
1300
|
}
|
|
@@ -1340,10 +1401,12 @@ declare namespace sharp {
|
|
|
1340
1401
|
}
|
|
1341
1402
|
|
|
1342
1403
|
interface TrimOptions {
|
|
1343
|
-
/**
|
|
1404
|
+
/** Background colour, parsed by the color module, defaults to that of the top-left pixel. (optional) */
|
|
1344
1405
|
background?: Color | undefined;
|
|
1345
|
-
/**
|
|
1406
|
+
/** Allowed difference from the above colour, a positive number. (optional, default 10) */
|
|
1346
1407
|
threshold?: number | undefined;
|
|
1408
|
+
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
|
1409
|
+
lineArt?: boolean | undefined;
|
|
1347
1410
|
}
|
|
1348
1411
|
|
|
1349
1412
|
interface RawOptions {
|
package/lib/libvips.js
CHANGED
|
@@ -16,7 +16,7 @@ const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).versio
|
|
|
16
16
|
|
|
17
17
|
const prebuiltPlatforms = [
|
|
18
18
|
'darwin-arm64', 'darwin-x64',
|
|
19
|
-
'linux-arm', 'linux-arm64', 'linux-x64',
|
|
19
|
+
'linux-arm', 'linux-arm64', 'linux-s390x', 'linux-x64',
|
|
20
20
|
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
21
21
|
'win32-ia32', 'win32-x64'
|
|
22
22
|
];
|
|
@@ -41,15 +41,23 @@ const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process
|
|
|
41
41
|
|
|
42
42
|
/* istanbul ignore next */
|
|
43
43
|
const buildPlatformArch = () => {
|
|
44
|
+
if (isEmscripten()) {
|
|
45
|
+
return 'wasm32';
|
|
46
|
+
}
|
|
44
47
|
/* eslint camelcase: ["error", { allow: ["^npm_config_"] }] */
|
|
45
48
|
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
|
46
|
-
|
|
49
|
+
const libc = typeof npm_config_libc === 'string' ? npm_config_libc : runtimeLibc();
|
|
50
|
+
return `${npm_config_platform || process.platform}${libc}-${npm_config_arch || process.arch}`;
|
|
47
51
|
};
|
|
48
52
|
|
|
49
53
|
const buildSharpLibvipsIncludeDir = () => {
|
|
50
54
|
try {
|
|
51
|
-
return require(
|
|
52
|
-
} catch {
|
|
55
|
+
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
56
|
+
} catch {
|
|
57
|
+
try {
|
|
58
|
+
return require('@img/sharp-libvips-dev/include');
|
|
59
|
+
} catch {}
|
|
60
|
+
}
|
|
53
61
|
/* istanbul ignore next */
|
|
54
62
|
return '';
|
|
55
63
|
};
|
|
@@ -64,12 +72,22 @@ const buildSharpLibvipsCPlusPlusDir = () => {
|
|
|
64
72
|
|
|
65
73
|
const buildSharpLibvipsLibDir = () => {
|
|
66
74
|
try {
|
|
67
|
-
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
68
|
-
} catch {
|
|
75
|
+
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
76
|
+
} catch {
|
|
77
|
+
try {
|
|
78
|
+
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
79
|
+
} catch {}
|
|
80
|
+
}
|
|
69
81
|
/* istanbul ignore next */
|
|
70
82
|
return '';
|
|
71
83
|
};
|
|
72
84
|
|
|
85
|
+
/* istanbul ignore next */
|
|
86
|
+
const isEmscripten = () => {
|
|
87
|
+
const { CC } = process.env;
|
|
88
|
+
return Boolean(CC && CC.endsWith('/emcc'));
|
|
89
|
+
};
|
|
90
|
+
|
|
73
91
|
const isRosetta = () => {
|
|
74
92
|
/* istanbul ignore next */
|
|
75
93
|
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
@@ -81,7 +99,7 @@ const isRosetta = () => {
|
|
|
81
99
|
|
|
82
100
|
/* istanbul ignore next */
|
|
83
101
|
const spawnRebuild = () =>
|
|
84
|
-
spawnSync(
|
|
102
|
+
spawnSync(`node-gyp rebuild --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, {
|
|
85
103
|
...spawnSyncOptions,
|
|
86
104
|
stdio: 'inherit'
|
|
87
105
|
}).status;
|
package/lib/output.js
CHANGED
|
@@ -163,39 +163,185 @@ function toBuffer (options, callback) {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
|
-
*
|
|
167
|
-
* This will also convert to and add a web-friendly sRGB ICC profile if appropriate,
|
|
168
|
-
* unless a custom output profile is provided.
|
|
169
|
-
*
|
|
170
|
-
* The default behaviour, when `withMetadata` is not used, is to convert to the device-independent
|
|
171
|
-
* sRGB colour space and strip all metadata, including the removal of any ICC profile.
|
|
166
|
+
* Keep all EXIF metadata from the input image in the output image.
|
|
172
167
|
*
|
|
173
168
|
* EXIF metadata is unsupported for TIFF output.
|
|
174
169
|
*
|
|
170
|
+
* @since 0.33.0
|
|
171
|
+
*
|
|
175
172
|
* @example
|
|
176
|
-
* sharp(
|
|
177
|
-
* .
|
|
178
|
-
* .
|
|
179
|
-
*
|
|
173
|
+
* const outputWithExif = await sharp(inputWithExif)
|
|
174
|
+
* .keepExif()
|
|
175
|
+
* .toBuffer();
|
|
176
|
+
*
|
|
177
|
+
* @returns {Sharp}
|
|
178
|
+
*/
|
|
179
|
+
function keepExif () {
|
|
180
|
+
this.options.keepMetadata |= 0b00001;
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Set EXIF metadata in the output image, ignoring any EXIF in the input image.
|
|
186
|
+
*
|
|
187
|
+
* @since 0.33.0
|
|
180
188
|
*
|
|
181
189
|
* @example
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
190
|
+
* const dataWithExif = await sharp(input)
|
|
191
|
+
* .withExif({
|
|
192
|
+
* IFD0: {
|
|
193
|
+
* Copyright: 'The National Gallery'
|
|
194
|
+
* },
|
|
195
|
+
* IFD3: {
|
|
196
|
+
* GPSLatitudeRef: 'N',
|
|
197
|
+
* GPSLatitude: '51/1 30/1 3230/100',
|
|
198
|
+
* GPSLongitudeRef: 'W',
|
|
199
|
+
* GPSLongitude: '0/1 7/1 4366/100'
|
|
200
|
+
* }
|
|
201
|
+
* })
|
|
202
|
+
* .toBuffer();
|
|
203
|
+
*
|
|
204
|
+
* @param {Object<string, Object<string, string>>} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
|
205
|
+
* @returns {Sharp}
|
|
206
|
+
* @throws {Error} Invalid parameters
|
|
207
|
+
*/
|
|
208
|
+
function withExif (exif) {
|
|
209
|
+
if (is.object(exif)) {
|
|
210
|
+
for (const [ifd, entries] of Object.entries(exif)) {
|
|
211
|
+
if (is.object(entries)) {
|
|
212
|
+
for (const [k, v] of Object.entries(entries)) {
|
|
213
|
+
if (is.string(v)) {
|
|
214
|
+
this.options.withExif[`exif-${ifd.toLowerCase()}-${k}`] = v;
|
|
215
|
+
} else {
|
|
216
|
+
throw is.invalidParameterError(`${ifd}.${k}`, 'string', v);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
throw is.invalidParameterError(ifd, 'object', entries);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
throw is.invalidParameterError('exif', 'object', exif);
|
|
225
|
+
}
|
|
226
|
+
this.options.withExifMerge = false;
|
|
227
|
+
return this.keepExif();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Update EXIF metadata from the input image in the output image.
|
|
232
|
+
*
|
|
233
|
+
* @since 0.33.0
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* const dataWithMergedExif = await sharp(inputWithExif)
|
|
237
|
+
* .withExifMerge({
|
|
238
|
+
* IFD0: {
|
|
239
|
+
* Copyright: 'The National Gallery'
|
|
195
240
|
* }
|
|
196
241
|
* })
|
|
197
242
|
* .toBuffer();
|
|
198
243
|
*
|
|
244
|
+
* @param {Object<string, Object<string, string>>} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
|
245
|
+
* @returns {Sharp}
|
|
246
|
+
* @throws {Error} Invalid parameters
|
|
247
|
+
*/
|
|
248
|
+
function withExifMerge (exif) {
|
|
249
|
+
this.withExif(exif);
|
|
250
|
+
this.options.withExifMerge = true;
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Keep ICC profile from the input image in the output image.
|
|
256
|
+
*
|
|
257
|
+
* Where necessary, will attempt to convert the output colour space to match the profile.
|
|
258
|
+
*
|
|
259
|
+
* @since 0.33.0
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* const outputWithIccProfile = await sharp(inputWithIccProfile)
|
|
263
|
+
* .keepIccProfile()
|
|
264
|
+
* .toBuffer();
|
|
265
|
+
*
|
|
266
|
+
* @returns {Sharp}
|
|
267
|
+
*/
|
|
268
|
+
function keepIccProfile () {
|
|
269
|
+
this.options.keepMetadata |= 0b01000;
|
|
270
|
+
return this;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Transform using an ICC profile and attach to the output image.
|
|
275
|
+
*
|
|
276
|
+
* This can either be an absolute filesystem path or
|
|
277
|
+
* built-in profile name (`srgb`, `p3`, `cmyk`).
|
|
278
|
+
*
|
|
279
|
+
* @since 0.33.0
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* const outputWithP3 = await sharp(input)
|
|
283
|
+
* .withIccProfile('p3')
|
|
284
|
+
* .toBuffer();
|
|
285
|
+
*
|
|
286
|
+
* @param {string} icc - Absolute filesystem path to output ICC profile or built-in profile name (srgb, p3, cmyk).
|
|
287
|
+
* @param {Object} [options]
|
|
288
|
+
* @param {number} [options.attach=true] Should the ICC profile be included in the output image metadata?
|
|
289
|
+
* @returns {Sharp}
|
|
290
|
+
* @throws {Error} Invalid parameters
|
|
291
|
+
*/
|
|
292
|
+
function withIccProfile (icc, options) {
|
|
293
|
+
if (is.string(icc)) {
|
|
294
|
+
this.options.withIccProfile = icc;
|
|
295
|
+
} else {
|
|
296
|
+
throw is.invalidParameterError('icc', 'string', icc);
|
|
297
|
+
}
|
|
298
|
+
this.keepIccProfile();
|
|
299
|
+
if (is.object(options)) {
|
|
300
|
+
if (is.defined(options.attach)) {
|
|
301
|
+
if (is.bool(options.attach)) {
|
|
302
|
+
if (!options.attach) {
|
|
303
|
+
this.options.keepMetadata &= ~0b01000;
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
throw is.invalidParameterError('attach', 'boolean', options.attach);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return this;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Keep all metadata (EXIF, ICC, XMP, IPTC) from the input image in the output image.
|
|
315
|
+
*
|
|
316
|
+
* The default behaviour, when `keepMetadata` is not used, is to convert to the device-independent
|
|
317
|
+
* sRGB colour space and strip all metadata, including the removal of any ICC profile.
|
|
318
|
+
*
|
|
319
|
+
* @since 0.33.0
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* const outputWithMetadata = await sharp(inputWithMetadata)
|
|
323
|
+
* .keepMetadata()
|
|
324
|
+
* .toBuffer();
|
|
325
|
+
*
|
|
326
|
+
* @returns {Sharp}
|
|
327
|
+
*/
|
|
328
|
+
function keepMetadata () {
|
|
329
|
+
this.options.keepMetadata = 0b11111;
|
|
330
|
+
return this;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Keep most metadata (EXIF, XMP, IPTC) from the input image in the output image.
|
|
335
|
+
*
|
|
336
|
+
* This will also convert to and add a web-friendly sRGB ICC profile if appropriate.
|
|
337
|
+
*
|
|
338
|
+
* Allows orientation and density to be set or updated.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* const outputSrgbWithMetadata = await sharp(inputRgbWithMetadata)
|
|
342
|
+
* .withMetadata()
|
|
343
|
+
* .toBuffer();
|
|
344
|
+
*
|
|
199
345
|
* @example
|
|
200
346
|
* // Set output metadata to 96 DPI
|
|
201
347
|
* const data = await sharp(input)
|
|
@@ -203,15 +349,14 @@ function toBuffer (options, callback) {
|
|
|
203
349
|
* .toBuffer();
|
|
204
350
|
*
|
|
205
351
|
* @param {Object} [options]
|
|
206
|
-
* @param {number} [options.orientation]
|
|
207
|
-
* @param {string} [options.icc='srgb'] Filesystem path to output ICC profile, relative to `process.cwd()`, defaults to built-in sRGB.
|
|
208
|
-
* @param {Object<Object>} [options.exif={}] Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data.
|
|
352
|
+
* @param {number} [options.orientation] Used to update the EXIF `Orientation` tag, integer between 1 and 8.
|
|
209
353
|
* @param {number} [options.density] Number of pixels per inch (DPI).
|
|
210
354
|
* @returns {Sharp}
|
|
211
355
|
* @throws {Error} Invalid parameters
|
|
212
356
|
*/
|
|
213
357
|
function withMetadata (options) {
|
|
214
|
-
this.
|
|
358
|
+
this.keepMetadata();
|
|
359
|
+
this.withIccProfile('srgb');
|
|
215
360
|
if (is.object(options)) {
|
|
216
361
|
if (is.defined(options.orientation)) {
|
|
217
362
|
if (is.integer(options.orientation) && is.inRange(options.orientation, 1, 8)) {
|
|
@@ -228,30 +373,10 @@ function withMetadata (options) {
|
|
|
228
373
|
}
|
|
229
374
|
}
|
|
230
375
|
if (is.defined(options.icc)) {
|
|
231
|
-
|
|
232
|
-
this.options.withMetadataIcc = options.icc;
|
|
233
|
-
} else {
|
|
234
|
-
throw is.invalidParameterError('icc', 'string filesystem path to ICC profile', options.icc);
|
|
235
|
-
}
|
|
376
|
+
this.withIccProfile(options.icc);
|
|
236
377
|
}
|
|
237
378
|
if (is.defined(options.exif)) {
|
|
238
|
-
|
|
239
|
-
for (const [ifd, entries] of Object.entries(options.exif)) {
|
|
240
|
-
if (is.object(entries)) {
|
|
241
|
-
for (const [k, v] of Object.entries(entries)) {
|
|
242
|
-
if (is.string(v)) {
|
|
243
|
-
this.options.withMetadataStrs[`exif-${ifd.toLowerCase()}-${k}`] = v;
|
|
244
|
-
} else {
|
|
245
|
-
throw is.invalidParameterError(`exif.${ifd}.${k}`, 'string', v);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
} else {
|
|
249
|
-
throw is.invalidParameterError(`exif.${ifd}`, 'object', entries);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
} else {
|
|
253
|
-
throw is.invalidParameterError('exif', 'object', options.exif);
|
|
254
|
-
}
|
|
379
|
+
this.withExifMerge(options.exif);
|
|
255
380
|
}
|
|
256
381
|
}
|
|
257
382
|
return this;
|
|
@@ -782,6 +907,7 @@ function trySetAnimationOptions (source, target) {
|
|
|
782
907
|
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
|
783
908
|
* @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
|
|
784
909
|
* @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
|
|
910
|
+
* @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
|
|
785
911
|
* @returns {Sharp}
|
|
786
912
|
* @throws {Error} Invalid options
|
|
787
913
|
*/
|
|
@@ -819,6 +945,10 @@ function tiff (options) {
|
|
|
819
945
|
throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
|
|
820
946
|
}
|
|
821
947
|
}
|
|
948
|
+
// miniswhite
|
|
949
|
+
if (is.defined(options.miniswhite)) {
|
|
950
|
+
this._setBooleanOption('tiffMiniswhite', options.miniswhite);
|
|
951
|
+
}
|
|
822
952
|
// pyramid
|
|
823
953
|
if (is.defined(options.pyramid)) {
|
|
824
954
|
this._setBooleanOption('tiffPyramid', options.pyramid);
|
|
@@ -1402,6 +1532,12 @@ module.exports = function (Sharp) {
|
|
|
1402
1532
|
// Public
|
|
1403
1533
|
toFile,
|
|
1404
1534
|
toBuffer,
|
|
1535
|
+
keepExif,
|
|
1536
|
+
withExif,
|
|
1537
|
+
withExifMerge,
|
|
1538
|
+
keepIccProfile,
|
|
1539
|
+
withIccProfile,
|
|
1540
|
+
keepMetadata,
|
|
1405
1541
|
withMetadata,
|
|
1406
1542
|
toFormat,
|
|
1407
1543
|
jpeg,
|