Fabric.js: Issue when applying grayscale filter to images

Created on 12 Mar 2018  路  14Comments  路  Source: fabricjs/fabric.js

Version

2.0.2

Test Case

http://jsfiddle.net/Da7SP/1144/

Steps to reproduce

If is_grayscale is set to true, some images (mostly PNG) are applied the grayscale filter, and are rendered in grayscale, however other images (mostly JPG) are not converted to grayscale and the console outputs this error:

RangeError: attempting to construct out-of-bounds TypedArray on ArrayBuffer
fabric.js:10068:14
copyGLTo2DPutImageData
https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js:10068:14
applyFilters
https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js:9931:13
applyFilters

Expected Behavior

Grayscale image

Actual Behavior

Error

bug

Most helpful comment

no i saying you just should change the fabric.textureSize to whatever you need and you think the hardware support.
fabric.textureSize = 4096 open more possibilities and should be well supported on many hardwares.

Or fallback to non webgl filtering if you think your customers cannot use it.

http://jsfiddle.net/Da7SP/1185/

All 14 comments

Ok, upon further testing I believe I figured it out, apparently it starts to happen when the images are large (>2048px).

oh this could be a bug, if the images are bigger than 2048 the filter is supposed to truncate them as long as you do not bump up filter size with the appropriate value, but the error should not be there.

What browser?

@asturur Firefox 59, did not try on other browsers.

I bypassed the error by resizing the images to 2048px if they are bigger (with the resize filter), before applying the grayscale filter, although it's no issue for me (because I don't really need images > 2048px wide), it's a hacky solution.

There is a proper parameter for filter size, you can find it in the changelog section of 2.0 in fabricjs.com

@asturur yes, I did that. But having to resize the image to apply a filter seems like a hacky workaround for me

@dwjorgeb I looked at others browsers since I too came across this!

for very large images (as in ones a user might upload to a CMS and make me get a sad face haha) this happens in every browser besides Chrome (64+) I've tried ( Edge HTML 16.16299, Firefox 59, Firefox Dev Edition 60.0b3 )

Here's an example: http://jsfiddle.net/Da7SP/1184/

In chrome after the filter is applied the image is cut down to match the canvas/texture size as mentioned here: http://fabricjs.com/fabric-filters

So are you saying @asturur that we should apply a resize filter to the image and then add it to the canvas before applying a filter?

I looked over both http://fabricjs.com/changes-introduction and http://fabricjs.com/changelog didn't see any mention of the parameter for filter size ( i very well could have hastily skipped over it)

@cdowdy I did this right before adding the image to the canvas:


imgObj.onload = function () {
    let scale = Math.min(1, (Math.min(width, height) / 2) / Math.max(imgObj.naturalWidth, imgObj.naturalHeight));

    let img = new fabric.Image(imgObj, {left: 10, top: 10, scaleX: scale, scaleY: scale});

    if (Math.max(imgObj.naturalWidth, imgObj.naturalHeight) > 2048) {
        let fscale = 2048 / Math.max(imgObj.naturalWidth, imgObj.naturalHeight);
        img.filters.push(new fabric.Image.filters.Resize({scaleX: fscale, scaleY: fscale}));
    }

    canvas.add(img);
    canvas.renderAll();
}

Thanks @dwjorgeb ! Much appreciated!

Here's an updated fiddle for the example I showed earlier for anyone coming across this
http://jsfiddle.net/trmqnc48/9/

I still have some tinkering to do with my methods/how they're ran since it still doesn't apply the filter at first but thats my issue!

2018-03-15_15-14-56

Thanks again!

@cdowdy http://jsfiddle.net/trmqnc48/25/ this is working for me

Sorry @dwjorgeb I should have clarified better. My personal project is still wonky (in the gif) the linked jsfiddle reduced test case works for me just fine!

@cdowdy but I changed the jsfiddle a bit, check it out

no i saying you just should change the fabric.textureSize to whatever you need and you think the hardware support.
fabric.textureSize = 4096 open more possibilities and should be well supported on many hardwares.

Or fallback to non webgl filtering if you think your customers cannot use it.

http://jsfiddle.net/Da7SP/1185/

Thanks to @cdowdy. After resizing , I'm able to apply filters.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

semiadam picture semiadam  路  3Comments

Vivek-KT picture Vivek-KT  路  3Comments

semiadam picture semiadam  路  3Comments

eddieyangtx picture eddieyangtx  路  5Comments

bhaskardas9475 picture bhaskardas9475  路  4Comments