From feba915be73e203e01a996b341743e12faeda2b7 Mon Sep 17 00:00:00 2001 From: Sjoerd Date: Sat, 22 Apr 2023 22:44:29 +0200 Subject: [PATCH] Fix: convolute not defaulting to 0, 0 as starting point --- packages/plugin-color/src/index.js | 8 +++----- packages/plugin-color/test/convolution.test.js | 16 ++++++++++++++++ .../plugin-color/test/images/tiles-blurred.png | Bin 0 -> 7859 bytes packages/plugin-color/test/images/tiles.jpg | Bin 0 -> 5696 bytes 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 packages/plugin-color/test/images/tiles-blurred.png create mode 100644 packages/plugin-color/test/images/tiles.jpg diff --git a/packages/plugin-color/src/index.js b/packages/plugin-color/src/index.js index 82489caa0..451bf2ce8 100644 --- a/packages/plugin-color/src/index.js +++ b/packages/plugin-color/src/index.js @@ -583,7 +583,7 @@ export default () => ({ * @param {number} w (optional) the width of the region to apply convolution to * @param {number} h (optional) the height of the region to apply convolution to * @param {function(Error, Jimp)} cb (optional) a callback for when complete - * @returns {Jimp }this for chaining of methods + * @returns {Jimp} this for chaining of methods */ convolute(kernel, x, y, w, h, cb) { if (!Array.isArray(kernel)) @@ -613,10 +613,8 @@ export default () => ({ } } - const ksize = (kernel.length - 1) / 2; - - x = isDef(x) ? x : ksize; - y = isDef(y) ? y : ksize; + x = isDef(x) ? x : 0; + y = isDef(y) ? y : 0; w = isDef(w) ? w : this.bitmap.width - x; h = isDef(h) ? h : this.bitmap.height - y; diff --git a/packages/plugin-color/test/convolution.test.js b/packages/plugin-color/test/convolution.test.js index 428ae52f3..e7abca10b 100644 --- a/packages/plugin-color/test/convolution.test.js +++ b/packages/plugin-color/test/convolution.test.js @@ -57,6 +57,12 @@ describe("Convolution", function () { [0, 1, 1], ]; + const blurM = [ + [1 / 9, 1 / 9, 1 / 9], + [1 / 9, 1 / 9, 1 / 9], + [1 / 9, 1 / 9, 1 / 9], + ]; + it("3x3 sharp matrix on EDGE_EXTEND", (done) => { expectToBeJGD( imgMid.clone().convolution(sharpM).getJGDSync(), @@ -150,6 +156,16 @@ describe("Convolution", function () { done(); }); + it("3x3 box blur matrix using convolute", async () => { + const expectedImg = await jimp.read( + getTestDir(__dirname) + "/images/tiles-blurred.png" + ); + + const image = await jimp.read(getTestDir(__dirname) + "/images/tiles.jpg"); + + expect(image.convolute(blurM).bitmap.data).toEqual(expectedImg.bitmap.data); + }); + it("new pixel value is greater than 255", async () => { const expectedImg = await jimp.read( getTestDir(__dirname) + "/images/qr-convoluted.png" diff --git a/packages/plugin-color/test/images/tiles-blurred.png b/packages/plugin-color/test/images/tiles-blurred.png new file mode 100644 index 0000000000000000000000000000000000000000..5b3da9b69ff39d9930a7583bb1f1dd52ec12d611 GIT binary patch literal 7859 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 literal 0 HcmV?d00001 diff --git a/packages/plugin-color/test/images/tiles.jpg b/packages/plugin-color/test/images/tiles.jpg new file mode 100644 index 0000000000000000000000000000000000000000..538c77e45997f5e4a0fa1b9104a472891dd35169 GIT binary patch literal 5696 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 CNE^Wb literal 0 HcmV?d00001