Ad

How To Disable Smoothing Of Images In Fabric.js When ToDataUrl() Is Called?

- 1 answer

Is it possible to disable smoothing of images within the canvas of Fabric.js when I export the canvas with toDataUrl()? I'm using version 3.6.2.

I have created the canvas with this code:

const canvas = new fabric.Canvas('canvas-1', {
    imageSmoothingEnabled: false
});

imageSmoothingEnabled turns off the smoothing in the canvas. However, when I call toDataUrl() with an multiplier and I show the result in an img, the smoothing is still there and it was also multiplied.

const dataUrl = canvas.toDataURL({format: 'png', multiplier: 3});
$imgageElement.attr('src', dataUrl); //jQuery

What do I have to do so that I get exactly what is displayed in the canvas?

Here is a fiddle. And here is report, since I think it is a bug.

Ad

Answer

One workaround seems to be overriding toCanvasElement with:

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;
};
Ad
source: stackoverflow.com
Ad