Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose optional minAmpl parameter of blur operation #4172

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/api-operation.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ When a `sigma` is provided, performs a slower, more accurate Gaussian blur.
| [options] | <code>Object</code> \| <code>number</code> \| <code>Boolean</code> | | |
| [options.sigma] | <code>number</code> | | a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`. |
| [options.precision] | <code>string</code> | <code>&quot;&#x27;integer&#x27;&quot;</code> | How accurate the operation should be, one of: integer, float, approximate. |
| [options.minAmplitude] | <code>number</code> | <code>0.2</code> | A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask. |

**Example**
```js
Expand Down
2 changes: 1 addition & 1 deletion docs/search-index.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ const Sharp = function (input, options) {
medianSize: 0,
blurSigma: 0,
precision: 'integer',
minAmpl: 0.2,
sharpenSigma: 0,
sharpenM1: 1,
sharpenM2: 2,
Expand Down
2 changes: 2 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,8 @@ declare namespace sharp {
interface BlurOptions {
/** A value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2` */
sigma: number;
/** A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask. */
minAmplitude?: number;
/** How accurate the operation should be, one of: integer, float, approximate. (optional, default "integer") */
precision?: Precision | undefined;
}
Expand Down
8 changes: 8 additions & 0 deletions lib/operation.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ function median (size) {
* @param {Object|number|Boolean} [options]
* @param {number} [options.sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
* @param {string} [options.precision='integer'] How accurate the operation should be, one of: integer, float, approximate.
* @param {number} [options.minAmplitude=0.2] A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
Expand All @@ -400,6 +401,13 @@ function blur (options) {
throw is.invalidParameterError('precision', 'one of: integer, float, approximate', options.precision);
}
}
if ('minAmplitude' in options) {
if (is.number(options.minAmplitude) && is.inRange(options.minAmplitude, 0.001, 1)) {
this.options.minAmpl = options.minAmplitude;
} else {
throw is.invalidParameterError('minAmplitude', 'number between 0.001 and 1', options.minAmplitude);
}
}
}

if (!is.defined(options)) {
Expand Down
5 changes: 3 additions & 2 deletions src/operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace sharp {
/*
* Gaussian blur. Use sigma of -1.0 for fast blur.
*/
VImage Blur(VImage image, double const sigma, VipsPrecision precision) {
VImage Blur(VImage image, double const sigma, VipsPrecision precision, double const minAmpl) {
if (sigma == -1.0) {
// Fast, mild blur - averages neighbouring pixels
VImage blur = VImage::new_matrixv(3, 3,
Expand All @@ -156,7 +156,8 @@ namespace sharp {
} else {
// Slower, accurate Gaussian blur
return StaySequential(image).gaussblur(sigma, VImage::option()
->set("precision", precision));
->set("precision", precision)
->set("min_ampl", minAmpl));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace sharp {
/*
* Gaussian blur. Use sigma of -1.0 for fast blur.
*/
VImage Blur(VImage image, double const sigma, VipsPrecision precision);
VImage Blur(VImage image, double const sigma, VipsPrecision precision, double const minAmpl);

/*
* Convolution with a kernel.
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ class PipelineWorker : public Napi::AsyncWorker {

// Blur
if (shouldBlur) {
image = sharp::Blur(image, baton->blurSigma, baton->precision);
image = sharp::Blur(image, baton->blurSigma, baton->precision, baton->minAmpl);
}

// Unflatten the image
Expand Down Expand Up @@ -1542,6 +1542,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->negateAlpha = sharp::AttrAsBool(options, "negateAlpha");
baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma");
baton->precision = sharp::AttrAsEnum<VipsPrecision>(options, "precision", VIPS_TYPE_PRECISION);
baton->minAmpl = sharp::AttrAsDouble(options, "minAmpl");
baton->brightness = sharp::AttrAsDouble(options, "brightness");
baton->saturation = sharp::AttrAsDouble(options, "saturation");
baton->hue = sharp::AttrAsInt32(options, "hue");
Expand Down
1 change: 1 addition & 0 deletions src/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct PipelineBaton {
bool negateAlpha;
double blurSigma;
VipsPrecision precision;
double minAmpl;
double brightness;
double saturation;
int hue;
Expand Down
1 change: 1 addition & 0 deletions test/types/sharp.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ sharp().blur();
sharp().blur(1);
sharp().blur({ sigma: 1 });
sharp().blur({ sigma: 1, precision: 'approximate' });
sharp().blur({ sigma: 1, minAmplitude: 0.8 });

sharp({
create: {
Expand Down
24 changes: 24 additions & 0 deletions test/unit/blur.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ describe('Blur', function () {
}, /Expected one of: integer, float, approximate for precision but received invalid of type string/);
});

it('invalid minAmplitude', function () {
assert.throws(function () {
sharp(fixtures.inputJpg).blur({ sigma: 1, minAmplitude: 0 });
}, /Expected number between 0.001 and 1 for minAmplitude but received 0 of type number/);

assert.throws(function () {
sharp(fixtures.inputJpg).blur({ sigma: 1, minAmplitude: 1.01 });
}, /Expected number between 0.001 and 1 for minAmplitude but received 1.01 of type number/);
});

it('specific radius 10 and precision approximate', async () => {
const approximate = await sharp(fixtures.inputJpg)
.resize(320, 240)
Expand All @@ -125,6 +135,20 @@ describe('Blur', function () {
await fixtures.assertSimilar(fixtures.expected('blur-10.jpg'), approximate);
});

it('specific radius 10 and minAmplitude 0.01', async () => {
const minAmplitudeLow = await sharp(fixtures.inputJpg)
.resize(320, 240)
.blur({ sigma: 10, minAmplitude: 0.01 })
.toBuffer();
const minAmplitudeDefault = await sharp(fixtures.inputJpg)
.resize(320, 240)
.blur(10)
.toBuffer();

assert.notDeepEqual(minAmplitudeLow, minAmplitudeDefault);
await fixtures.assertSimilar(fixtures.expected('blur-10.jpg'), minAmplitudeLow);
});

it('options.sigma is required if options object is passed', function () {
assert.throws(function () {
sharp(fixtures.inputJpg).blur({ precision: 'invalid' });
Expand Down