Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
qpincon committed Oct 22, 2024
1 parent 1533bf9 commit 512dffa
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 0 deletions.
24 changes: 24 additions & 0 deletions docs/api-operation.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,30 @@ const gaussianBlurred = await sharp(input)
.toBuffer();
```

## dilate

Dilate the image.

**Throws**:

- <code>Error</code> Invalid parameters

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [width] | <code>number</code> | <code>1</code> | a value between 1 and XX representing the mask size |

## erode

Erodes the image.

**Throws**:

- <code>Error</code> Invalid parameters

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [width] | <code>number</code> | <code>1</code> | a value between 1 and XX representing the mask size |


## flatten
> flatten([options]) ⇒ <code>Sharp</code>
Expand Down
2 changes: 2 additions & 0 deletions lib/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ const Sharp = function (input, options) {
trimBackground: [],
trimThreshold: -1,
trimLineArt: false,
dilateWidth: 0,
erodeWidth: 0,
gamma: 0,
gammaOut: 0,
greyscale: false,
Expand Down
40 changes: 40 additions & 0 deletions lib/operation.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,44 @@ function blur (options) {
return this;
}

/**
* Dilate the image.
* @param {Number} [width] dilate width.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function dilate (width) {
if (!is.defined(width)) {
// No arguments: default to 1px dilation (3x3 mask)
this.options.dilateWidth = 1;
} else if (is.integer(width) && width > 0) {
// Numeric argument: specific width
this.options.dilateWidth = width;
} else {
throw is.invalidParameterError('dilate', 'positive integer', dilate);
}
return this;
}

/**
* Erode the image.
* @param {Number} [width] erode width.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function erode (width) {
if (!is.defined(width)) {
// No arguments: default to 1px erosion (3x3 mask)
this.options.erodeWidth = 1;
} else if (is.integer(width) && width > 0) {
// Numeric argument: specific width
this.options.erodeWidth = width;
} else {
throw is.invalidParameterError('erode', 'positive integer', erode);
}
return this;
}

/**
* Merge alpha transparency channel, if any, with a background, then remove the alpha channel.
*
Expand Down Expand Up @@ -940,6 +978,8 @@ module.exports = function (Sharp) {
flop,
affine,
sharpen,
erode,
dilate,
median,
blur,
flatten,
Expand Down
24 changes: 24 additions & 0 deletions src/operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -472,4 +472,28 @@ namespace sharp {
}
}

/*
* Dilate an image
*/
VImage Dilate(VImage image, int const width) {
const int maskWidth = 2*width + 1;
VImage mask = VImage::new_matrix(maskWidth, maskWidth);

return image.morph(
mask,
VIPS_OPERATION_MORPHOLOGY_DILATE).invert();
}

/*
* Erode an image
*/
VImage Erode(VImage image, int const width) {
const int maskWidth = 2*width + 1;
VImage mask = VImage::new_matrix(maskWidth, maskWidth);

return image.morph(
mask,
VIPS_OPERATION_MORPHOLOGY_ERODE).invert();
}

} // namespace sharp
9 changes: 9 additions & 0 deletions src/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ namespace sharp {
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
VipsExtend extendWith, std::vector<double> background, int nPages, int *pageHeight);

/*
* Dilate an image
*/
VImage Dilate(VImage image, int const maskWidth);

/*
* Erode an image
*/
VImage Erode(VImage image, int const maskWidth);
} // namespace sharp

#endif // SRC_OPERATIONS_H_
12 changes: 12 additions & 0 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,16 @@ class PipelineWorker : public Napi::AsyncWorker {
image = sharp::Threshold(image, baton->threshold, baton->thresholdGrayscale);
}

// Dilate - must happen before blurring, due to the utility of dilating after thresholding
if (baton->dilateWidth != 0) {
image = sharp::Dilate(image, baton->dilateWidth);
}

// Erode - must happen before blurring, due to the utility of eroding after thresholding
if (baton->erodeWidth != 0) {
image = sharp::Erode(image, baton->erodeWidth);
}

// Blur
if (shouldBlur) {
image = sharp::Blur(image, baton->blurSigma, baton->precision, baton->minAmpl);
Expand Down Expand Up @@ -1564,6 +1574,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");
baton->linearA = sharp::AttrAsVectorOfDouble(options, "linearA");
baton->linearB = sharp::AttrAsVectorOfDouble(options, "linearB");
baton->dilateWidth = sharp::AttrAsUint32(options, "dilateWidth");
baton->erodeWidth = sharp::AttrAsUint32(options, "erodeWidth");
baton->greyscale = sharp::AttrAsBool(options, "greyscale");
baton->normalise = sharp::AttrAsBool(options, "normalise");
baton->normaliseLower = sharp::AttrAsUint32(options, "normaliseLower");
Expand Down
4 changes: 4 additions & 0 deletions src/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ struct PipelineBaton {
int trimOffsetTop;
std::vector<double> linearA;
std::vector<double> linearB;
int dilateWidth;
int erodeWidth;
double gamma;
double gammaOut;
bool greyscale;
Expand Down Expand Up @@ -273,6 +275,8 @@ struct PipelineBaton {
trimOffsetTop(0),
linearA{},
linearB{},
dilateWidth(0),
erodeWidth(0),
gamma(0.0),
greyscale(false),
normalise(false),
Expand Down
Binary file added test/fixtures/dot-and-lines.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/expected/dilate-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/expected/erode-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions test/fixtures/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ module.exports = {

inputJPGBig: getPath('flowers.jpeg'),

inputPngDotAndLines: getPath('dot-and-lines.png'),

inputPngStripesV: getPath('stripesV.png'),
inputPngStripesH: getPath('stripesH.png'),

Expand Down
38 changes: 38 additions & 0 deletions test/unit/dilate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

const assert = require('assert');

const sharp = require('../../');
const fixtures = require('../fixtures');

describe('Dilate', function () {
it('dilate 1 png', function (done) {
sharp(fixtures.inputPngDotAndLines)
.dilate(1)
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
fixtures.assertSimilar(fixtures.expected('dilate-1.png'), data, done);
});
});

it('dilate 1 png - default width', function (done) {
sharp(fixtures.inputPngDotAndLines)
.dilate()
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
fixtures.assertSimilar(fixtures.expected('dilate-1.png'), data, done);
});
});

it('invalid dilation width', function () {
assert.throws(function () {
sharp(fixtures.inputJpg).dilate(-1);
});
});
});
38 changes: 38 additions & 0 deletions test/unit/erode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

const assert = require('assert');

const sharp = require('../../');
const fixtures = require('../fixtures');

describe('Erode', function () {
it('erode 1 png', function (done) {
sharp(fixtures.inputPngDotAndLines)
.erode(1)
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
fixtures.assertSimilar(fixtures.expected('erode-1.png'), data, done);
});
});

it('erode 1 png - default width', function (done) {
sharp(fixtures.inputPngDotAndLines)
.erode()
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
fixtures.assertSimilar(fixtures.expected('erode-1.png'), data, done);
});
});

it('invalid erosion width', function () {
assert.throws(function () {
sharp(fixtures.inputJpg).erode(-1);
});
});
});

0 comments on commit 512dffa

Please sign in to comment.