Fabric.js克隆图片恢复默认滤镜异常问题求助
Fabric.js 滤镜编辑后无法恢复默认值的问题修复
问题根源
- 克隆对象基于处理后的图片:你当前是从已应用滤镜的主图片克隆生成临时编辑图,转成DataURL后,临时图的像素已经是滤镜处理后的结果。即便清空临时图的
filters数组,也无法恢复到原始状态——因为像素本身已经被修改,滤镜数组只是记录后续要应用的效果,无法逆转已处理的像素。 - 滤镜数组直接引用赋值:
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
相关产品推荐
相关产品推荐

