Search code examples
jqueryfabricjsimagefilter

Lanczos image filter is not applying to image


I am using lanczos filter in my project to make image good quality. Specially for uploded images on canvas. I already used Fabric.js demos · Realtime lanczos http://fabricjs.com/lanczos-webgl It is working for me.

But It's not working for two or more images.

When I added two or more images on canvas and I scaled up one images. Working ok. But I scaled up another image then first one get blur or not visible correctly. It affecting on other images when I scaled images.

Please suggest some solution on above situation.

Below is my script:

        jQuery('#cust_image').change(function(e) {
            var file = e.target.files[0];  //alert(JSON.stringify(e.target.files[0]));
            var reader = new FileReader();
            var r = canvas.getRetinaScaling();
            reader.onload = function(f) {
                var data = f.target.result;  
                console.log(data);
                fabric.Image.fromURL(data, function(cimg) {
                    var oImg = cimg.set({
                        left: 0,
                        top: 0,
                        angle: 00,
                        centeredScaling: true,
                        hasRotatingPoint: false
                    }).scale(0.3);

                    lanczosFilter.scaleX = lanczosFilter.scaleY = oImg.scaleX * r;
                    oImg.lockScalingFlip = true;
                    oImg.minScaleLimit = 0.025;
                    oImg.padding = 5;
                    oImg.filters = [lanczosFilter];
                    //oImg.hoverCursor = 'crossHair';

                    oImg.on('scaling', function(opt) {
                        var filters = [];
                        var sX = Math.abs(this.scaleX) * r, sY = Math.abs(this.scaleY) * r;
                        if (sX > 0.01 && sY > 0.01 && sX < 1 && sY < 1) {
                            if (sX <= 0.2 || sY <= 0.2) {
                                lanczosFilter.lanczosLobes = 2;
                            } else if (sX <= 0.05 || sY <= 0.05) {
                                lanczosFilter.lanczosLobes = 1;
                            } else {
                                lanczosFilter.lanczosLobes = 3;
                            }
                            lanczosFilter.scaleX = sX;
                            lanczosFilter.scaleY = sY;
                            filters.push(lanczosFilter);
                        }
                        this.filters = filters;
                    });

                    canvas.add(oImg).renderAll();
                    var a = canvas.setActiveObject(oImg);   
                    canvas.on('before:render', function() {
                        oImg.applyFilters();                    
                    });
                    var dataURL = canvas.toDataURL({
                        format: 'png',
                        quality: 0.8
                    });     
                });
            };
            reader.readAsDataURL(file);
        });

Check screenshot for problem. In this image drangon image looking good and clear.But the pokemon image not looking good and blur image. Check this fiddle https://jsfiddle.net/AppleDev/xpvt214o/179163/

enter image description here

Thanks in Advance


Solution

  • I think the problem in your code is that you are sharing the same filter with all the images, so the images are like randomly resized depending on the order you do scaling.

    Please check this version of your code and see if it helps.

    The difference is that i m creating a new filter for each image you load on canvas.

    I think this job is better done using the specific Image.resizeFilter property, unsure how to now preapare an example

    $(function() {
    	var canvas = new fabric.Canvas('can',{
    		imageSmoothingEnabled: false,
    		enableRetinaScaling: false,
    		fireRightClick: true,
    		stopContextMenu: true,
    	});
      
      function newFilter() {
        return new fabric.Image.filters.Resize({
          scaleX: 1,
          scaleY: 1,
          resizeType: 'lanczos',
          lanczosLobes: 3,
        });
      }
      
      /* For Image quality */
    	
    
    	var p = {
    		x: 0,
    		y: 0,
    	};
      
      jQuery('#cust_image').change(function(e) {
                var file = e.target.files[0];  //alert(JSON.stringify(e.target.files[0]));
                var reader = new FileReader();
                var r = canvas.getRetinaScaling();
                reader.onload = function(f) {
                    var data = f.target.result;  
                    fabric.Image.fromURL(data, function(oImg) {
                        oImg.set({
                            left: 0,
                            top: 0,
                            angle: 00,
                            centeredScaling: true,
                            hasRotatingPoint: false
                        }).scale(0.3);
                        var lanczosFilter = newFilter();
                        lanczosFilter.scaleX = lanczosFilter.scaleY = oImg.scaleX * r;
                        oImg.lockScalingFlip = true;
                        oImg.minScaleLimit = 0.025;
                        oImg.padding = 5;
                        oImg.filters = [lanczosFilter];
    
                        oImg.on('scaling', function(opt) {
                            var lanczosFilter = this.filters[0];
                            var sX = Math.abs(this.scaleX) * r, sY = Math.abs(this.scaleY) * r;
                            if (sX > 0.01 && sY > 0.01 && sX < 1 && sY < 1) {
                                if (sX <= 0.2 || sY <= 0.2) {
                                    lanczosFilter.lanczosLobes = 2;
                                } else if (sX <= 0.05 || sY <= 0.05) {
                                    lanczosFilter.lanczosLobes = 1;
                                } else {
                                    lanczosFilter.lanczosLobes = 3;
                                }
                                lanczosFilter.scaleX = sX;
                                lanczosFilter.scaleY = sY;
                            }
                        });
                        canvas.add(oImg);
                        var a = canvas.setActiveObject(oImg);   
                        canvas.on('before:render', function() {
                            oImg.applyFilters();                    
                        });     
                    });
                };
                reader.readAsDataURL(file);
            });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.3/fabric.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input type="file" id="cust_image" class="form-control" />
    <canvas id="can" height="600" width="600"></canvas>