Jimp: Reproduce Gimp Convolution in jimp (Convolution matrix)

Created on 29 Nov 2017  路  4Comments  路  Source: oliver-moran/jimp

I can not reproduce the same result I have on Gimp. What I do wrong?

Original Image:
photo_2017-11-28_12-46-00

With gimp I use this procedure: Filter-> Generic-> Convolution Matrix.
Settings:
cattura
Result:
photo_2017-11-28_12-46-00_d

With jimp "0.2.28" on Node:

original_image = original_image.convolute([
            [0, 0, 0, 0, 0],
            [0, 1, 1, 1, 0],
            [0, 1, 0, 1, 0],
            [0, 1, 1, 1, 0],
            [0, 0, 0, 0, 0],
        ]);

Result:
1

Thanks!

bug

Most helpful comment

@steffkelsey why monkey patch when you can make a PR. please do!

All 4 comments

The problem is that the convolution function in Jimp does not handle the case new pixel value is greater than 255

You can try monkey-patching the convolute function to this:
```Jimp.prototype.convolute = function (kernel, x, y, w, h, cb) {
if (!Array.isArray(kernel))
return throwError.call(this, "the kernel must be an array", cb);

if (typeof x === "function") {
    cb = x;
    x = y = w = h = null;
} else {
    if (isDef(x) && typeof x !== "number")
        return throwError.call(this, "x must be a number", cb);
    if (isDef(y) && typeof y !== "number")
        return throwError.call(this, "y must be a number", cb);
    if (isDef(w) && typeof w !== "number")
        return throwError.call(this, "w must be a number", cb);
    if (isDef(h) && typeof h !== "number")
        return throwError.call(this, "h must be a number", cb);
}

let 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();
this.scanQuiet(x, y, w, h, function (xx, yx, idx) {
    var value = applyKernel(source, kernel, xx, yx);

    this.bitmap.data[idx] = Math.max(0, Math.min(value[0], 255));
    this.bitmap.data[idx + 1] = Math.max(0, Math.min(value[1], 255));
    this.bitmap.data[idx + 2] = Math.max(0, Math.min(value[2], 255));
});

if (isNodePattern(cb)) return cb.call(this, null, this);
else return this;

};```

That would keep all the final values between 0 and 255.

@steffkelsey why monkey patch when you can make a PR. please do!

Released in v0.4.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Yimiprod picture Yimiprod  路  5Comments

Favna picture Favna  路  4Comments

molipha picture molipha  路  6Comments

dtrofimov picture dtrofimov  路  5Comments

alyyousuf7 picture alyyousuf7  路  3Comments