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

Reproduce Gimp Convolution in jimp (Convolution matrix) #368

Closed
jBernavaPrah opened this issue Nov 29, 2017 · 4 comments · Fixed by #587
Closed

Reproduce Gimp Convolution in jimp (Convolution matrix) #368

jBernavaPrah opened this issue Nov 29, 2017 · 4 comments · Fixed by #587
Labels
bug there is a bug in the way jimp behaves

Comments

@jBernavaPrah
Copy link

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!

@andq-ibl
Copy link

andq-ibl commented Feb 5, 2018

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

@steffkelsey
Copy link

You can try monkey-patching the convolute function to this:

    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.

@hipstersmoothie
Copy link
Collaborator

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

@hipstersmoothie
Copy link
Collaborator

Released in v0.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug there is a bug in the way jimp behaves
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants