尝试在 fabric js 中使用 setSrc() 更改图像 src 时出现“filter.applyTo 不是函数”错误

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

目前,我正在开发图像编辑器,它允许我裁剪图像并应用滤镜。 我正在使用 fabric js 版本 1.7.22。 我想实现裁剪功能。 所以我的裁剪流程如下所示:

  1. 使用插件和裁剪图像的 ger base64 裁剪图像。
  2. 从 base64 生成 blobUrl,这有助于在 fabric js 中显示图像 canvas。
  3. 裁剪图像后,我将旧图像 src 替换为新图像。

当图像没有滤镜时效果很好。

但是当我尝试先在图像中设置滤镜然后尝试使用 setSrc() 函数替换 src 时。

它抛出如下错误 filter.applyTo is not a function

我创建了一个 fiddle 用于演示在应用过滤器后替换 src。 https://jsfiddle.net/Mark_1998/98gLhcb4/1/

而且我无法升级我的 fabric js 版本。如果有可用的补丁,那么

请帮助我。

问题出在这段代码:

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

您将 canvas.getActiveObject().toObject() 作为 options 对象传递,该对象在 setSrc() -> setElement() -> _initConfig() 中分配给您的图像。

toObject() 序列化您的 fabric.Image,并且 filters 数组不再包含实际的 fabric.Filter,而是它的序列化版本。因此,它没有带有 applyTo() 方法的原型,因此当 fabric 在 setSrc().

之后尝试将滤镜重新应用到您的图像时出现错误 filter.applyTo is not a function

您需要选择您实际想要传递的属性,而不是将整个序列化对象作为选项传递。由于我不确定您的要求是什么,我尝试用以下代码替换上面的代码并且它对我有用:

  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);

请注意 options.crossOrigin = true - 没有它您将无法应用过滤器。