Reputation: 329
Is there a way to antialiase image that added to canvas using fabric.js I'm having trouble to do this with scaleToHeight function. I couldn't find any suitable option in fabric library.
var canvas = new fabric.Canvas('canvas');
var url = 'https://grafikoan.files.wordpress.com/2012/10/spheres-grafic-design-grafikoan-hd-300-p-2.png';
fabric.Image.fromURL(url, function (oImg) {
oImg.scaleToHeight(canvas.getHeight());
canvas.add(oImg);
canvas.renderAll();
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="canvas" width=400 height=300></canvas>
As you can see this image looks jagged.
Upvotes: 2
Views: 3741
Reputation: 14731
fabricjs has its own resize filtering to avoid jaggies. Resize filter, with type "sliceHack" is the fastest/good result one. If you do not need dynamic filtering on resize you can also use lanzcos filtering, bilinear, fast hermit.
UPDATE: Since july 2017 with fabric 2.0 there is a sort of lanzcos webgl implementation that is good quality and very fast. By default webgl is on, and there are no alternative alghoritm in the webgl, lanzcos only.
var canvas = new fabric.Canvas('canvas');
var url = 'https://grafikoan.files.wordpress.com/2012/10/spheres-grafic-design-grafikoan-hd-300-p-2.png';
fabric.Image.fromURL(url, function (oImg) {
var scaling = canvas.getHeight() / oImg.height;
oImg.filters.push(new fabric.Image.filters.Resize({
resizeType: 'sliceHack', scaleX: scaling , scaleY: scaling
}));
canvas.add(oImg);
oImg.applyFilters(canvas.renderAll.bind(canvas));
},{ crossOrigin: 'Anonymous' });
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="http://www.deltalink.it/andreab/fabric/fabric.js"></script>
<canvas id="canvas" width=400 height=300></canvas>
Please check this link for a working example with no CoR issue.
http://www.deltalink.it/andreab/fabric/resize.html
Compare normale image and sliceHack image, the filter will kick in once you resize.
Here more examples: https://github.com/kangax/fabric.js/issues/1741
Upvotes: 4
Reputation: 105035
The original image is 10X the size of the desired size.
Scaling downward by 10X is causing your "jaggies". Yes, scaling downward can cause jaggies just like scaling upward can cause jaggies.
You can lessen the jaggies by incrementally scaling the original image downward towards the desired size.
Here is example code and a Demo:
The original image is downscaled 4 times by half and then scaleToHeight
is applied to get the final size of the fabric.Image.
var canvas = new fabric.Canvas('canvas');
var downscaledImg;
var img=new Image();
img.onload=start;
img.src="https://grafikoan.files.wordpress.com/2012/10/spheres-grafic-design-grafikoan-hd-300-p-2.png";
function start(){
// create a canvas that is 4x smaller than the original img
downscaledImg=downscale(img,4);
// create a fabric.Image from the downscaled image
var fImg=new fabric.Image(downscaledImg);
fImg.scaleToHeight(canvas.getHeight());
canvas.add(fImg);
canvas.renderAll();
}
function downscale(img,halfCount){
var cc;
var c=document.createElement('canvas');
c.width=img.width/2;
c.height=img.height/2;
c.getContext('2d').drawImage(img,0,0,img.width/2,img.height/2);
halfCount--;
for(var i=0;i<halfCount;i++){
cc=document.createElement('canvas');
cc.width=c.width/2;
cc.height=c.height/2;
cc.getContext('2d').drawImage(c,0,0,c.width/2,c.height/2);
halfCount--;
c=cc;
}
return(c);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="canvas" width=400 height=300></canvas> </body>
Upvotes: 4