You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fabric.js克隆图片恢复默认滤镜异常问题求助

Fabric.js 滤镜编辑后无法恢复默认值的问题修复

问题根源

  1. 克隆对象基于处理后的图片:你当前是从已应用滤镜的主图片克隆生成临时编辑图,转成DataURL后,临时图的像素已经是滤镜处理后的结果。即便清空临时图的filters数组,也无法恢复到原始状态——因为像素本身已经被修改,滤镜数组只是记录后续要应用的效果,无法逆转已处理的像素。
  2. 滤镜数组直接引用赋值:custom_image.filters = copy_image.filters是引用赋值,主图和临时图共享同一个滤镜数组,后续操作会导致两者状态意外同步。

修复方案

1. 保留原始图片副本

在首次加载图片时,保存未经过任何滤镜处理的原始图片数据,确保每次编辑都基于原始素材,而非处理后的主图片。

2. 深拷贝滤镜对象

赋值滤镜时避免直接引用,通过深拷贝创建独立的滤镜数组,防止主图和临时图的滤镜状态互相干扰。

修改后的完整代码

var addEvent = function(el, type, handler) {
  if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
}

var image_base64 = ' data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/...';
var custom_image;
var copy_canvas;
var copy_image;
var originalImageData; // 保存原始图片DataURL

const canvas = new fabric.Canvas('c', {
  width: 300,
  height: 300,
  backgroundColor: '#ffffff',
  selectable: false,
  selection: false,
  preserveObjectStacking: true,
  allowTouchScrolling: true,
});
canvas.renderAll();

fabric.Image.fromURL(image_base64, (image) => {
  custom_image = image.set({
    top: 0,
    left: 0,
    selectable: false,
    scalable: false,
    controls: false,
  });
  custom_image.scaleToHeight(300);
  custom_image.scaleToWidth(300);
  // 保存原始图片的未滤镜处理DataURL
  originalImageData = custom_image.toDataURL({ format: 'jpeg', quality: 1 });
  canvas.add(custom_image);
  canvas.renderAll();
});

addEvent(document.querySelector('#start-edit'), 'click', (e) => {
  copy_canvas = new fabric.Canvas('copy-canvas', {
    width: 300,
    height: 300,
    backgroundColor: '#aaaaaa',
    selectable: false,
    selection: false,
    preserveObjectStacking: true,
    allowTouchScrolling: true,
  });
  copy_canvas.renderAll();

  // 基于原始图片创建临时编辑图,而非当前已处理的主图片
  fabric.Image.fromURL(originalImageData, (image) => {
    copy_image = image.set({
      top: 0,
      left: 0,
      selectable: false,
      scalable: false,
      controls: false,
    });
    copy_image.scaleToHeight(300);
    copy_image.scaleToWidth(300);
    copy_canvas.add(copy_image);
    copy_canvas.renderAll();

    setTimeout(() => {
      // 应用滤镜到临时图
      copy_image.filters = [new fabric.Image.filters.Saturation({
        saturation: 0.5
      })];
      copy_image.applyFilters();
      copy_canvas.renderAll();
    }, 1000);
  });
});

addEvent(document.querySelector('#finish-edit'), 'click', (e) => {
  // 深拷贝滤镜数组,避免引用共享
  custom_image.filters = copy_image.filters.map(filter => {
    return new fabric.Image.filters[filter.type](filter.toObject());
  });
  custom_image.applyFilters();
  canvas.renderAll();
  copy_canvas.dispose();
});

效果说明

修改后,每次点击"start filter"都会加载原始图片作为编辑基底,即使之前保存过滤镜效果,临时图的初始状态也会是原始无滤镜的图片,此时应用默认滤镜值(如saturation:0)就能正确恢复原始效果。同时,深拷贝滤镜数组确保主图和临时图的滤镜状态完全独立,不会出现互相干扰的问题。

内容的提问来源于stack exchange,提问作者Insomnia88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:13:13