`filter.applyTo is not a function` error when try to change image src using setSrc() in fabric js

Viewed 507

Currently, I am Working on image editor that allows me to crop an image and apply a filter. I am using fabric js version 1.7.22. I want to implement crop functionality. so my cropping flow is like Below :

  1. crop image using a plugin and ger base64 of the cropped image.
  2. generate blobUrl from base64 which help to display image in fabric js canvas.
  3. After Cropping the image, I Just replace old image src with new One.

It works fine when an image has no filter.

but when I try to set a filter in the image first then try to replace src using setSrc() function.

It throws an error like Below filter.applyTo is not a function

I have created one fiddle for demonstrating to replace src after the apply filter. https://jsfiddle.net/Mark_1998/98gLhcb4/1/

And I Can't upgrade my fabric js version. If any patch Available then

Please Help Me.

1 Answers

The problem lies in this piece of code:

canvas.getActiveObject().setSrc('http://fabricjs.com/assets/pug_small.jpg', function(){
  canvas.renderAll();
}, canvas.getActiveObject().toObject());

You're passing canvas.getActiveObject().toObject() as an options object, which is assigned to your image in setSrc() -> setElement() -> _initConfig().

toObject() serializes your fabric.Image, and filters array no longer contains the actual fabric.Filter, but rather a serialized version of it. So, it does not have a prototype with applyTo() method on it, hence the error filter.applyTo is not a function when fabric tries to reapply filters to your image after setSrc().

Instead of passing the whole serialized object as options, you'll need to pick the properties you actually want to be passed. As I'm not sure about what your requirements are, I tried replacing the above code with the following and it worked for me:

  var options = canvas.getActiveObject().toObject();
  delete options.filters;
  options.crossOrigin = true;
  canvas.getActiveObject().setSrc('http://fabricjs.com/assets/pug_small.jpg', function(){
    canvas.renderAll();
  }, options);

Note the options.crossOrigin = true - you won't be able to apply filters without it.

Related