sharp 0.30.2 → 0.30.3
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/lib/colour.js +9 -0
- package/lib/composite.js +16 -0
- package/lib/constructor.js +5 -2
- package/lib/input.js +16 -5
- package/lib/operation.js +136 -28
- package/lib/sharp.js +1 -1
- package/package.json +2 -2
- package/src/operations.cc +10 -3
- package/src/operations.h +2 -1
- package/src/pipeline.cc +8 -4
- package/src/pipeline.h +10 -4
package/lib/colour.js
CHANGED
|
@@ -19,6 +19,11 @@ const colourspace = {
|
|
|
19
19
|
* Tint the image using the provided chroma while preserving the image luminance.
|
|
20
20
|
* An alpha channel may be present and will be unchanged by the operation.
|
|
21
21
|
*
|
|
22
|
+
* @example
|
|
23
|
+
* const output = await sharp(input)
|
|
24
|
+
* .tint({ r: 255, g: 240, b: 16 })
|
|
25
|
+
* .toBuffer();
|
|
26
|
+
*
|
|
22
27
|
* @param {string|Object} rgb - parsed by the [color](https://www.npmjs.org/package/color) module to extract chroma values.
|
|
23
28
|
* @returns {Sharp}
|
|
24
29
|
* @throws {Error} Invalid parameter
|
|
@@ -37,6 +42,10 @@ function tint (rgb) {
|
|
|
37
42
|
* This may be overridden by other sharp operations such as `toColourspace('b-w')`,
|
|
38
43
|
* which will produce an output image containing one color channel.
|
|
39
44
|
* An alpha channel may be present, and will be unchanged by the operation.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const output = await sharp(input).greyscale().toBuffer();
|
|
48
|
+
*
|
|
40
49
|
* @param {Boolean} [greyscale=true]
|
|
41
50
|
* @returns {Sharp}
|
|
42
51
|
*/
|
package/lib/composite.js
CHANGED
|
@@ -56,6 +56,21 @@ const blend = {
|
|
|
56
56
|
* @since 0.22.0
|
|
57
57
|
*
|
|
58
58
|
* @example
|
|
59
|
+
* await sharp(background)
|
|
60
|
+
* .composite([
|
|
61
|
+
* { input: layer1, gravity: 'northwest' },
|
|
62
|
+
* { input: layer2, gravity: 'southeast' },
|
|
63
|
+
* ])
|
|
64
|
+
* .toFile('combined.png');
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* const output = await sharp('input.gif', { animated: true })
|
|
68
|
+
* .composite([
|
|
69
|
+
* { input: 'overlay.png', tile: true, blend: 'saturate' }
|
|
70
|
+
* ])
|
|
71
|
+
* .toBuffer();
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
59
74
|
* sharp('input.png')
|
|
60
75
|
* .rotate(180)
|
|
61
76
|
* .resize(300)
|
|
@@ -89,6 +104,7 @@ const blend = {
|
|
|
89
104
|
* @param {Number} [images[].raw.width]
|
|
90
105
|
* @param {Number} [images[].raw.height]
|
|
91
106
|
* @param {Number} [images[].raw.channels]
|
|
107
|
+
* @param {boolean} [images[].animated=false] - Set to `true` to read all frames/pages of an animated image.
|
|
92
108
|
* @param {boolean} [images[].failOnError=true] - @see {@link /api-constructor#parameters|constructor parameters}
|
|
93
109
|
* @param {number|boolean} [images[].limitInputPixels=268402689] - @see {@link /api-constructor#parameters|constructor parameters}
|
|
94
110
|
* @returns {Sharp}
|
package/lib/constructor.js
CHANGED
|
@@ -186,8 +186,11 @@ const Sharp = function (input, options) {
|
|
|
186
186
|
medianSize: 0,
|
|
187
187
|
blurSigma: 0,
|
|
188
188
|
sharpenSigma: 0,
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
sharpenM1: 1,
|
|
190
|
+
sharpenM2: 2,
|
|
191
|
+
sharpenX1: 2,
|
|
192
|
+
sharpenY2: 10,
|
|
193
|
+
sharpenY3: 20,
|
|
191
194
|
threshold: 0,
|
|
192
195
|
thresholdGrayscale: true,
|
|
193
196
|
trimThreshold: 0,
|
package/lib/input.js
CHANGED
|
@@ -299,8 +299,8 @@ function _isStreamInput () {
|
|
|
299
299
|
*
|
|
300
300
|
* - `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
|
|
301
301
|
* - `size`: Total size of image in bytes, for Stream and Buffer input only
|
|
302
|
-
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration)
|
|
303
|
-
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration)
|
|
302
|
+
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
|
|
303
|
+
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
|
|
304
304
|
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation)
|
|
305
305
|
* - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
|
306
306
|
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat)
|
|
@@ -343,6 +343,17 @@ function _isStreamInput () {
|
|
|
343
343
|
* // data contains a WebP image half the width and height of the original JPEG
|
|
344
344
|
* });
|
|
345
345
|
*
|
|
346
|
+
* @example
|
|
347
|
+
* // Based on EXIF rotation metadata, get the right-side-up width and height:
|
|
348
|
+
*
|
|
349
|
+
* const size = getNormalSize(await sharp(input).metadata());
|
|
350
|
+
*
|
|
351
|
+
* function getNormalSize({ width, height, orientation }) {
|
|
352
|
+
* return orientation || 0 >= 5
|
|
353
|
+
* ? { width: height, height: width }
|
|
354
|
+
* : { width, height };
|
|
355
|
+
* }
|
|
356
|
+
*
|
|
346
357
|
* @param {Function} [callback] - called with the arguments `(err, metadata)`
|
|
347
358
|
* @returns {Promise<Object>|Sharp}
|
|
348
359
|
*/
|
|
@@ -401,9 +412,9 @@ function metadata (callback) {
|
|
|
401
412
|
* - `maxX` (x-coordinate of one of the pixel where the maximum lies)
|
|
402
413
|
* - `maxY` (y-coordinate of one of the pixel where the maximum lies)
|
|
403
414
|
* - `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
|
|
404
|
-
* - `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any
|
|
405
|
-
* - `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any
|
|
406
|
-
* - `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram
|
|
415
|
+
* - `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any.
|
|
416
|
+
* - `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any.
|
|
417
|
+
* - `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram.
|
|
407
418
|
*
|
|
408
419
|
* **Note**: Statistics are derived from the original input image. Any operations performed on the image must first be
|
|
409
420
|
* written to a buffer in order to run `stats` on the result (see third example).
|
package/lib/operation.js
CHANGED
|
@@ -63,6 +63,10 @@ function rotate (angle, options) {
|
|
|
63
63
|
/**
|
|
64
64
|
* Flip the image about the vertical Y axis. This always occurs after rotation, if any.
|
|
65
65
|
* The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* const output = await sharp(input).flip().toBuffer();
|
|
69
|
+
*
|
|
66
70
|
* @param {Boolean} [flip=true]
|
|
67
71
|
* @returns {Sharp}
|
|
68
72
|
*/
|
|
@@ -74,6 +78,10 @@ function flip (flip) {
|
|
|
74
78
|
/**
|
|
75
79
|
* Flop the image about the horizontal X axis. This always occurs after rotation, if any.
|
|
76
80
|
* The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* const output = await sharp(input).flop().toBuffer();
|
|
84
|
+
*
|
|
77
85
|
* @param {Boolean} [flop=true]
|
|
78
86
|
* @returns {Sharp}
|
|
79
87
|
*/
|
|
@@ -185,40 +193,107 @@ function affine (matrix, options) {
|
|
|
185
193
|
* When a `sigma` is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space.
|
|
186
194
|
* Separate control over the level of sharpening in "flat" and "jagged" areas is available.
|
|
187
195
|
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
* @
|
|
196
|
+
* See {@link https://www.libvips.org/API/current/libvips-convolution.html#vips-sharpen|libvips sharpen} operation.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* const data = await sharp(input).sharpen().toBuffer();
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* const data = await sharp(input).sharpen({ sigma: 2 }).toBuffer();
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* const data = await sharp(input)
|
|
206
|
+
* .sharpen({
|
|
207
|
+
* sigma: 2,
|
|
208
|
+
* m1: 0
|
|
209
|
+
* m2: 3,
|
|
210
|
+
* x1: 3,
|
|
211
|
+
* y2: 15,
|
|
212
|
+
* y3: 15,
|
|
213
|
+
* })
|
|
214
|
+
* .toBuffer();
|
|
215
|
+
*
|
|
216
|
+
* @param {Object|number} [options] - if present, is an Object with attributes or (deprecated) a number for `options.sigma`.
|
|
217
|
+
* @param {number} [options.sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
|
218
|
+
* @param {number} [options.m1=1.0] - the level of sharpening to apply to "flat" areas.
|
|
219
|
+
* @param {number} [options.m2=2.0] - the level of sharpening to apply to "jagged" areas.
|
|
220
|
+
* @param {number} [options.x1=2.0] - threshold between "flat" and "jagged"
|
|
221
|
+
* @param {number} [options.y2=10.0] - maximum amount of brightening.
|
|
222
|
+
* @param {number} [options.y3=20.0] - maximum amount of darkening.
|
|
223
|
+
* @param {number} [flat] - (deprecated) see `options.m1`.
|
|
224
|
+
* @param {number} [jagged] - (deprecated) see `options.m2`.
|
|
191
225
|
* @returns {Sharp}
|
|
192
226
|
* @throws {Error} Invalid parameters
|
|
193
227
|
*/
|
|
194
|
-
function sharpen (
|
|
195
|
-
if (!is.defined(
|
|
228
|
+
function sharpen (options, flat, jagged) {
|
|
229
|
+
if (!is.defined(options)) {
|
|
196
230
|
// No arguments: default to mild sharpen
|
|
197
231
|
this.options.sharpenSigma = -1;
|
|
198
|
-
} else if (is.bool(
|
|
199
|
-
//
|
|
200
|
-
this.options.sharpenSigma =
|
|
201
|
-
} else if (is.number(
|
|
202
|
-
//
|
|
203
|
-
this.options.sharpenSigma =
|
|
204
|
-
//
|
|
232
|
+
} else if (is.bool(options)) {
|
|
233
|
+
// Deprecated boolean argument: apply mild sharpen?
|
|
234
|
+
this.options.sharpenSigma = options ? -1 : 0;
|
|
235
|
+
} else if (is.number(options) && is.inRange(options, 0.01, 10000)) {
|
|
236
|
+
// Deprecated numeric argument: specific sigma
|
|
237
|
+
this.options.sharpenSigma = options;
|
|
238
|
+
// Deprecated control over flat areas
|
|
205
239
|
if (is.defined(flat)) {
|
|
206
240
|
if (is.number(flat) && is.inRange(flat, 0, 10000)) {
|
|
207
|
-
this.options.
|
|
241
|
+
this.options.sharpenM1 = flat;
|
|
208
242
|
} else {
|
|
209
243
|
throw is.invalidParameterError('flat', 'number between 0 and 10000', flat);
|
|
210
244
|
}
|
|
211
245
|
}
|
|
212
|
-
//
|
|
246
|
+
// Deprecated control over jagged areas
|
|
213
247
|
if (is.defined(jagged)) {
|
|
214
248
|
if (is.number(jagged) && is.inRange(jagged, 0, 10000)) {
|
|
215
|
-
this.options.
|
|
249
|
+
this.options.sharpenM2 = jagged;
|
|
216
250
|
} else {
|
|
217
251
|
throw is.invalidParameterError('jagged', 'number between 0 and 10000', jagged);
|
|
218
252
|
}
|
|
219
253
|
}
|
|
254
|
+
} else if (is.plainObject(options)) {
|
|
255
|
+
if (is.number(options.sigma) && is.inRange(options.sigma, 0.01, 10000)) {
|
|
256
|
+
this.options.sharpenSigma = options.sigma;
|
|
257
|
+
} else {
|
|
258
|
+
throw is.invalidParameterError('options.sigma', 'number between 0.01 and 10000', options.sigma);
|
|
259
|
+
}
|
|
260
|
+
if (is.defined(options.m1)) {
|
|
261
|
+
if (is.number(options.m1) && is.inRange(options.m1, 0, 10000)) {
|
|
262
|
+
this.options.sharpenM1 = options.m1;
|
|
263
|
+
} else {
|
|
264
|
+
throw is.invalidParameterError('options.m1', 'number between 0 and 10000', options.m1);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (is.defined(options.m2)) {
|
|
268
|
+
if (is.number(options.m2) && is.inRange(options.m2, 0, 10000)) {
|
|
269
|
+
this.options.sharpenM2 = options.m2;
|
|
270
|
+
} else {
|
|
271
|
+
throw is.invalidParameterError('options.m2', 'number between 0 and 10000', options.m2);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (is.defined(options.x1)) {
|
|
275
|
+
if (is.number(options.x1) && is.inRange(options.x1, 0, 10000)) {
|
|
276
|
+
this.options.sharpenX1 = options.x1;
|
|
277
|
+
} else {
|
|
278
|
+
throw is.invalidParameterError('options.x1', 'number between 0 and 10000', options.x1);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (is.defined(options.y2)) {
|
|
282
|
+
if (is.number(options.y2) && is.inRange(options.y2, 0, 10000)) {
|
|
283
|
+
this.options.sharpenY2 = options.y2;
|
|
284
|
+
} else {
|
|
285
|
+
throw is.invalidParameterError('options.y2', 'number between 0 and 10000', options.y2);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (is.defined(options.y3)) {
|
|
289
|
+
if (is.number(options.y3) && is.inRange(options.y3, 0, 10000)) {
|
|
290
|
+
this.options.sharpenY3 = options.y3;
|
|
291
|
+
} else {
|
|
292
|
+
throw is.invalidParameterError('options.y3', 'number between 0 and 10000', options.y3);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
220
295
|
} else {
|
|
221
|
-
throw is.invalidParameterError('sigma', 'number between 0.01 and 10000',
|
|
296
|
+
throw is.invalidParameterError('sigma', 'number between 0.01 and 10000', options);
|
|
222
297
|
}
|
|
223
298
|
return this;
|
|
224
299
|
}
|
|
@@ -226,6 +301,13 @@ function sharpen (sigma, flat, jagged) {
|
|
|
226
301
|
/**
|
|
227
302
|
* Apply median filter.
|
|
228
303
|
* When used without parameters the default window is 3x3.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* const output = await sharp(input).median().toBuffer();
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* const output = await sharp(input).median(5).toBuffer();
|
|
310
|
+
*
|
|
229
311
|
* @param {number} [size=3] square mask size: size x size
|
|
230
312
|
* @returns {Sharp}
|
|
231
313
|
* @throws {Error} Invalid parameters
|
|
@@ -356,6 +438,10 @@ function negate (options) {
|
|
|
356
438
|
|
|
357
439
|
/**
|
|
358
440
|
* Enhance output image contrast by stretching its luminance to cover the full dynamic range.
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* const output = await sharp(input).normalise().toBuffer();
|
|
444
|
+
*
|
|
359
445
|
* @param {Boolean} [normalise=true]
|
|
360
446
|
* @returns {Sharp}
|
|
361
447
|
*/
|
|
@@ -366,6 +452,10 @@ function normalise (normalise) {
|
|
|
366
452
|
|
|
367
453
|
/**
|
|
368
454
|
* Alternative spelling of normalise.
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* const output = await sharp(input).normalize().toBuffer();
|
|
458
|
+
*
|
|
369
459
|
* @param {Boolean} [normalize=true]
|
|
370
460
|
* @returns {Sharp}
|
|
371
461
|
*/
|
|
@@ -381,6 +471,14 @@ function normalize (normalize) {
|
|
|
381
471
|
*
|
|
382
472
|
* @since 0.28.3
|
|
383
473
|
*
|
|
474
|
+
* @example
|
|
475
|
+
* const output = await sharp(input)
|
|
476
|
+
* .clahe({
|
|
477
|
+
* width: 3,
|
|
478
|
+
* height: 3,
|
|
479
|
+
* })
|
|
480
|
+
* .toBuffer();
|
|
481
|
+
*
|
|
384
482
|
* @param {Object} options
|
|
385
483
|
* @param {number} options.width - integer width of the region in pixels.
|
|
386
484
|
* @param {number} options.height - integer height of the region in pixels.
|
|
@@ -590,28 +688,38 @@ function recomb (inputMatrix) {
|
|
|
590
688
|
* @since 0.22.1
|
|
591
689
|
*
|
|
592
690
|
* @example
|
|
593
|
-
*
|
|
691
|
+
* // increase brightness by a factor of 2
|
|
692
|
+
* const output = await sharp(input)
|
|
594
693
|
* .modulate({
|
|
595
|
-
* brightness: 2
|
|
596
|
-
* })
|
|
694
|
+
* brightness: 2
|
|
695
|
+
* })
|
|
696
|
+
* .toBuffer();
|
|
597
697
|
*
|
|
598
|
-
*
|
|
698
|
+
* @example
|
|
699
|
+
* // hue-rotate by 180 degrees
|
|
700
|
+
* const output = await sharp(input)
|
|
599
701
|
* .modulate({
|
|
600
|
-
* hue: 180
|
|
601
|
-
* })
|
|
702
|
+
* hue: 180
|
|
703
|
+
* })
|
|
704
|
+
* .toBuffer();
|
|
602
705
|
*
|
|
603
|
-
*
|
|
706
|
+
* @example
|
|
707
|
+
* // increase lightness by +50
|
|
708
|
+
* const output = await sharp(input)
|
|
604
709
|
* .modulate({
|
|
605
|
-
* lightness: 50
|
|
606
|
-
* })
|
|
710
|
+
* lightness: 50
|
|
711
|
+
* })
|
|
712
|
+
* .toBuffer();
|
|
607
713
|
*
|
|
714
|
+
* @example
|
|
608
715
|
* // decreate brightness and saturation while also hue-rotating by 90 degrees
|
|
609
|
-
* sharp(input)
|
|
716
|
+
* const output = await sharp(input)
|
|
610
717
|
* .modulate({
|
|
611
718
|
* brightness: 0.5,
|
|
612
719
|
* saturation: 0.5,
|
|
613
|
-
* hue: 90
|
|
614
|
-
* })
|
|
720
|
+
* hue: 90,
|
|
721
|
+
* })
|
|
722
|
+
* .toBuffer();
|
|
615
723
|
*
|
|
616
724
|
* @param {Object} [options]
|
|
617
725
|
* @param {number} [options.brightness] Brightness multiplier
|
package/lib/sharp.js
CHANGED
|
@@ -21,7 +21,7 @@ try {
|
|
|
21
21
|
'- Consult the installation documentation: https://sharp.pixelplumbing.com/install'
|
|
22
22
|
);
|
|
23
23
|
// Check loaded
|
|
24
|
-
if (process.platform === 'win32') {
|
|
24
|
+
if (process.platform === 'win32' || /symbol/.test(err.message)) {
|
|
25
25
|
const loadedModule = Object.keys(require.cache).find((i) => /[\\/]build[\\/]Release[\\/]sharp(.*)\.node$/.test(i));
|
|
26
26
|
if (loadedModule) {
|
|
27
27
|
const [, loadedPackage] = loadedModule.match(/node_modules[\\/]([^\\/]+)[\\/]/);
|
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.30.
|
|
4
|
+
"version": "0.30.3",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"exif-reader": "^1.0.3",
|
|
144
144
|
"icc": "^2.0.0",
|
|
145
145
|
"license-checker": "^25.0.1",
|
|
146
|
-
"mocha": "^9.2.
|
|
146
|
+
"mocha": "^9.2.2",
|
|
147
147
|
"mock-fs": "^5.1.2",
|
|
148
148
|
"nyc": "^15.1.0",
|
|
149
149
|
"prebuild": "^11.0.3",
|
package/src/operations.cc
CHANGED
|
@@ -209,7 +209,8 @@ namespace sharp {
|
|
|
209
209
|
/*
|
|
210
210
|
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
|
211
211
|
*/
|
|
212
|
-
VImage Sharpen(VImage image, double const sigma, double const
|
|
212
|
+
VImage Sharpen(VImage image, double const sigma, double const m1, double const m2,
|
|
213
|
+
double const x1, double const y2, double const y3) {
|
|
213
214
|
if (sigma == -1.0) {
|
|
214
215
|
// Fast, mild sharpen
|
|
215
216
|
VImage sharpen = VImage::new_matrixv(3, 3,
|
|
@@ -224,8 +225,14 @@ namespace sharp {
|
|
|
224
225
|
if (colourspaceBeforeSharpen == VIPS_INTERPRETATION_RGB) {
|
|
225
226
|
colourspaceBeforeSharpen = VIPS_INTERPRETATION_sRGB;
|
|
226
227
|
}
|
|
227
|
-
return image
|
|
228
|
-
VImage::option()
|
|
228
|
+
return image
|
|
229
|
+
.sharpen(VImage::option()
|
|
230
|
+
->set("sigma", sigma)
|
|
231
|
+
->set("m1", m1)
|
|
232
|
+
->set("m2", m2)
|
|
233
|
+
->set("x1", x1)
|
|
234
|
+
->set("y2", y2)
|
|
235
|
+
->set("y3", y3))
|
|
229
236
|
.colourspace(colourspaceBeforeSharpen);
|
|
230
237
|
}
|
|
231
238
|
}
|
package/src/operations.h
CHANGED
|
@@ -64,7 +64,8 @@ namespace sharp {
|
|
|
64
64
|
/*
|
|
65
65
|
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
|
66
66
|
*/
|
|
67
|
-
VImage Sharpen(VImage image, double const sigma, double const
|
|
67
|
+
VImage Sharpen(VImage image, double const sigma, double const m1, double const m2,
|
|
68
|
+
double const x1, double const y2, double const y3);
|
|
68
69
|
|
|
69
70
|
/*
|
|
70
71
|
Threshold an image
|
package/src/pipeline.cc
CHANGED
|
@@ -354,7 +354,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
354
354
|
}
|
|
355
355
|
|
|
356
356
|
bool const shouldPremultiplyAlpha = sharp::HasAlpha(image) &&
|
|
357
|
-
(shouldResize || shouldBlur || shouldConv || shouldSharpen
|
|
357
|
+
(shouldResize || shouldBlur || shouldConv || shouldSharpen);
|
|
358
358
|
|
|
359
359
|
// Premultiply image alpha channel before all transformations to avoid
|
|
360
360
|
// dark fringing around bright pixels
|
|
@@ -577,7 +577,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
577
577
|
|
|
578
578
|
// Sharpen
|
|
579
579
|
if (shouldSharpen) {
|
|
580
|
-
image = sharp::Sharpen(image, baton->sharpenSigma, baton->
|
|
580
|
+
image = sharp::Sharpen(image, baton->sharpenSigma, baton->sharpenM1, baton->sharpenM2,
|
|
581
|
+
baton->sharpenX1, baton->sharpenY2, baton->sharpenY3);
|
|
581
582
|
}
|
|
582
583
|
|
|
583
584
|
// Composite
|
|
@@ -1400,8 +1401,11 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1400
1401
|
baton->lightness = sharp::AttrAsDouble(options, "lightness");
|
|
1401
1402
|
baton->medianSize = sharp::AttrAsUint32(options, "medianSize");
|
|
1402
1403
|
baton->sharpenSigma = sharp::AttrAsDouble(options, "sharpenSigma");
|
|
1403
|
-
baton->
|
|
1404
|
-
baton->
|
|
1404
|
+
baton->sharpenM1 = sharp::AttrAsDouble(options, "sharpenM1");
|
|
1405
|
+
baton->sharpenM2 = sharp::AttrAsDouble(options, "sharpenM2");
|
|
1406
|
+
baton->sharpenX1 = sharp::AttrAsDouble(options, "sharpenX1");
|
|
1407
|
+
baton->sharpenY2 = sharp::AttrAsDouble(options, "sharpenY2");
|
|
1408
|
+
baton->sharpenY3 = sharp::AttrAsDouble(options, "sharpenY3");
|
|
1405
1409
|
baton->threshold = sharp::AttrAsInt32(options, "threshold");
|
|
1406
1410
|
baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale");
|
|
1407
1411
|
baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
|
package/src/pipeline.h
CHANGED
|
@@ -90,8 +90,11 @@ struct PipelineBaton {
|
|
|
90
90
|
double lightness;
|
|
91
91
|
int medianSize;
|
|
92
92
|
double sharpenSigma;
|
|
93
|
-
double
|
|
94
|
-
double
|
|
93
|
+
double sharpenM1;
|
|
94
|
+
double sharpenM2;
|
|
95
|
+
double sharpenX1;
|
|
96
|
+
double sharpenY2;
|
|
97
|
+
double sharpenY3;
|
|
95
98
|
int threshold;
|
|
96
99
|
bool thresholdGrayscale;
|
|
97
100
|
double trimThreshold;
|
|
@@ -234,8 +237,11 @@ struct PipelineBaton {
|
|
|
234
237
|
lightness(0),
|
|
235
238
|
medianSize(0),
|
|
236
239
|
sharpenSigma(0.0),
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
sharpenM1(1.0),
|
|
241
|
+
sharpenM2(2.0),
|
|
242
|
+
sharpenX1(2.0),
|
|
243
|
+
sharpenY2(10.0),
|
|
244
|
+
sharpenY3(20.0),
|
|
239
245
|
threshold(0),
|
|
240
246
|
thresholdGrayscale(true),
|
|
241
247
|
trimThreshold(0.0),
|