如何在调用 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 中显示的内容?

这是一个 fiddle. And here is report,因为我认为这是一个错误。

它不能完全解决您的问题,但您可以使用 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;
};