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.
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;
};