如何在调用 toDataUrl() 时禁用 Fabric.js 中的图像平滑?
How to disable smoothing of images in Fabric.js when toDataUrl() is called?
当我用 toDataUrl() 导出 canvas 时,是否可以禁用 Fabric.js 的 canvas 内的图像平滑?我使用的是 3.6.2 版本。
我用这段代码创建了 canvas:
const canvas = new fabric.Canvas('canvas-1', {
imageSmoothingEnabled: false
});
imageSmoothingEnabled 关闭 canvas 中的平滑。但是,当我用乘数调用 toDataUrl()
并在 img 中显示结果时,平滑仍然存在并且也被乘以。
const dataUrl = canvas.toDataURL({format: 'png', multiplier: 3});
$imgageElement.attr('src', dataUrl); //jQuery
我必须做什么才能准确了解 canvas 中显示的内容?
它不能完全解决您的问题,但您可以使用 Resize filter:
以某种方式使其不那么明显
var img = new fabric.Image(img, {
left: 10,
top: 10,
angle: 5,
zoom: 3,
objectCaching: false
});
img.filters.push(new fabric.Image.filters.Resize({
resizeType: 'sliceHack',
scaleX: 4,
scaleY: 4
}));
img.applyFilters();
img.scale(4);
canvas.add(img);
这里是working fiddle.
一种解决方法似乎是用以下方法覆盖 toCanvasElement:
const canvas = new fabric.Canvas('canvas-1', {
imageSmoothingEnabled: false
});
canvas.toCanvasElement = function (multiplier, cropping) {
multiplier = multiplier || 1;
cropping = cropping || {};
var scaledWidth = (cropping.width || this.width) * multiplier,
scaledHeight = (cropping.height || this.height) * multiplier,
zoom = this.getZoom(),
originalWidth = this.width,
originalHeight = this.height,
newZoom = zoom * multiplier,
vp = this.viewportTransform,
translateX = (vp[4] - (cropping.left || 0)) * multiplier,
translateY = (vp[5] - (cropping.top || 0)) * multiplier,
originalInteractive = this.interactive,
newVp = [newZoom, 0, 0, newZoom, translateX, translateY],
originalRetina = this.enableRetinaScaling,
canvasEl = fabric.util.createCanvasElement(),
originalContextTop = this.contextTop;
canvasEl.width = scaledWidth;
canvasEl.height = scaledHeight;
this.contextTop = null;
this.enableRetinaScaling = false;
this.interactive = false;
this.viewportTransform = newVp;
this.width = scaledWidth;
this.height = scaledHeight;
this.calcViewportBoundaries();
var ctx = canvasEl.getContext('2d'); // replaced
ctx.imageSmoothingEnabled = false; // this.renderCanvas(canvasEl.getContext('2d'), this._objects);
this.renderCanvas(ctx, this._objects); // with these 3 lines
this.viewportTransform = vp;
this.width = originalWidth;
this.height = originalHeight;
this.calcViewportBoundaries();
this.interactive = originalInteractive;
this.enableRetinaScaling = originalRetina;
this.contextTop = originalContextTop;
return canvasEl;
};
当我用 toDataUrl() 导出 canvas 时,是否可以禁用 Fabric.js 的 canvas 内的图像平滑?我使用的是 3.6.2 版本。
我用这段代码创建了 canvas:
const canvas = new fabric.Canvas('canvas-1', {
imageSmoothingEnabled: false
});
imageSmoothingEnabled 关闭 canvas 中的平滑。但是,当我用乘数调用 toDataUrl()
并在 img 中显示结果时,平滑仍然存在并且也被乘以。
const dataUrl = canvas.toDataURL({format: 'png', multiplier: 3});
$imgageElement.attr('src', dataUrl); //jQuery
我必须做什么才能准确了解 canvas 中显示的内容?
它不能完全解决您的问题,但您可以使用 Resize filter:
以某种方式使其不那么明显var img = new fabric.Image(img, {
left: 10,
top: 10,
angle: 5,
zoom: 3,
objectCaching: false
});
img.filters.push(new fabric.Image.filters.Resize({
resizeType: 'sliceHack',
scaleX: 4,
scaleY: 4
}));
img.applyFilters();
img.scale(4);
canvas.add(img);
这里是working fiddle.
一种解决方法似乎是用以下方法覆盖 toCanvasElement:
const canvas = new fabric.Canvas('canvas-1', {
imageSmoothingEnabled: false
});
canvas.toCanvasElement = function (multiplier, cropping) {
multiplier = multiplier || 1;
cropping = cropping || {};
var scaledWidth = (cropping.width || this.width) * multiplier,
scaledHeight = (cropping.height || this.height) * multiplier,
zoom = this.getZoom(),
originalWidth = this.width,
originalHeight = this.height,
newZoom = zoom * multiplier,
vp = this.viewportTransform,
translateX = (vp[4] - (cropping.left || 0)) * multiplier,
translateY = (vp[5] - (cropping.top || 0)) * multiplier,
originalInteractive = this.interactive,
newVp = [newZoom, 0, 0, newZoom, translateX, translateY],
originalRetina = this.enableRetinaScaling,
canvasEl = fabric.util.createCanvasElement(),
originalContextTop = this.contextTop;
canvasEl.width = scaledWidth;
canvasEl.height = scaledHeight;
this.contextTop = null;
this.enableRetinaScaling = false;
this.interactive = false;
this.viewportTransform = newVp;
this.width = scaledWidth;
this.height = scaledHeight;
this.calcViewportBoundaries();
var ctx = canvasEl.getContext('2d'); // replaced
ctx.imageSmoothingEnabled = false; // this.renderCanvas(canvasEl.getContext('2d'), this._objects);
this.renderCanvas(ctx, this._objects); // with these 3 lines
this.viewportTransform = vp;
this.width = originalWidth;
this.height = originalHeight;
this.calcViewportBoundaries();
this.interactive = originalInteractive;
this.enableRetinaScaling = originalRetina;
this.contextTop = originalContextTop;
return canvasEl;
};