jimp-dev/jimp

[Feature] Add optional divisor to convolute()

Open

#763 opened on 2019年7月24日

GitHub で見る
 (1 comment) (0 reactions) (0 assignees)JavaScript (785 forks)batch import
enhancementhelp wantedsolution in issue

Repository metrics

Stars
 (13,218 stars)
PR merge metrics
 (30d に merged PR はありません)

説明

Is your feature request related to a problem? Please describe. When searching the Internet for convolution kernels, one often finds some which normalize at the end of the calculation with division.

A typical example for a Gaussian blur might look like this:

| 1   4   6   4   1 |
| 4  16  24  16   4 |
| 6  24  36  24   6 |
| 4  16  24  16   4 |
| 1   4   6   4   1 | / 256

To find the equivalent version which doesn't include a divisor step, one would need to laboriously divide each of those integers with the divisor, resulting in something which might look like this:

[0.00390625,   0.015625,   0.0234375,   0.015625,   0.00390625],
[0.015625,     0.0625,     0.09375,     0.0625,     0.015625],
[0.0234375,    0.09375,    0.140625,    0.09375,    0.0234375],
[0.015625,     0.0625,     0.09375,     0.0625,     0.015625],
[0.00390625,   0.015625,   0.0234375,   0.015625,   0.00390625]

Describe the solution you'd like What would be nice would be if the convolute() functions added another (optional) argument called divisor which defaults to 1.

Describe alternatives you've considered Noting that my app is a Node.js daemon, I was able to monkey-patch node_modules/@jimp/plugin-color/dist/index.js inside the convolute() function definition like this:

      var ksize = (kernel.length - 1) / 2;
      x = isDef(x) ? x : ksize;
      y = isDef(y) ? y : ksize;
      w = isDef(w) ? w : this.bitmap.width - x;
      h = isDef(h) ? h : this.bitmap.height - y;
      var source = this.cloneQuiet();
      // Begin edit ------------------
      var divisor = 256; // Imagine instead that the function accepted it as an argument
      // End edit --------------------
      this.scanQuiet(x, y, w, h, function (xx, yx, idx) {
        var value = applyKernel(source, kernel, xx, yx);
        // Begin edit ------------------
        value[0] /= divisor;
        value[1] /= divisor;
        value[2] /= divisor;
        // End edit --------------------
        this.bitmap.data[idx] = this.constructor.limit255(value[0]);
        this.bitmap.data[idx + 1] = this.constructor.limit255(value[1]);
        this.bitmap.data[idx + 2] = this.constructor.limit255(value[2]);
      });

It worked perfectly, normalizing the darkness/lightness of the resulting blur. Without this, it's problematic coming up with a good-looking matrix whose values sum to one (unless you have access to Matlab).

Of course, there appear to be several interfaces other than just @jimp/plugin-color/dist but I didn't use those.

コントリビューターガイド