0

I want to downsize a PNG/JPG image in KineticJS without losing quality.

I did the following but it leads to very poor quality:

var stage = new Kinetic.Stage({
    container: 'container',
    width: 1000,
    height: 1000
});
var layer = new Kinetic.Layer();

var imageObj = new Image();
imageObj.onload = function () {
    var someImage = new Kinetic.Image({
        image: imageObj,
    });

    // add the shape to the layer
    layer.add(someImage);

    // add the layer to the stage
    stage.add(layer);

    someImage.scale({
        x: 500,
        y: 500
    });
    layer.draw();
};
imageObj.src = // some image;
Greg
  • 2,163
  • 1
  • 21
  • 23
Michael
  • 32,527
  • 49
  • 210
  • 370
  • 1
    As PNG images consist of *pixels* -- discrete points -- downscaling them will *always* downgrade the image. "Without loosing quality" only makes sense when you imagine a 100x100 white square with a 50x50 red square in its center; this can be downscaled "without loosing quality" to 1/2, 1/5th, 1/10th and 1/25th of its original size. – Jongware Apr 17 '14 at 19:29

1 Answers1

1

You can get good results by down-scaling the image in increments.

Here's a function that takes a source image (or canvas) and scales it down:

function scaleImage(source,scaleFactor){
    var canvas=document.createElement("canvas");
    var ctx=canvas.getContext("2d");
    canvas.width=source.width*scaleFactor;
    canvas.height=source.height*scaleFactor;
    ctx.drawImage(source,0,0,source.width*scaleFactor,source.height*scaleFactor);
    return(canvas);
}

The scaleImage function could be used like this to downscale a very large image:

A Demo: http://jsfiddle.net/m1erickson/zYLLe/

var img=new Image();
img.onload=start;
img.src="hugeImage.png";
function start(){

    // c1 is 0.50 the size of img

    var c1=scaleImage(img,0.50);

    // c2 is 0.50 the size of c1  (==25% of the original img)

    var c2=scaleImage(c1,0.50);

    // and then create a Kinetic.Image using c2 as a source

    image1 = new Kinetic.Image({
        x:10,
        y:10,
        image:c2,
        draggable: true
    });
    layer.add(image1);
    layer.draw();
}
markE
  • 102,905
  • 11
  • 164
  • 176
  • Does it mean the more scale steps I take the better is the quality? – Michael Apr 17 '14 at 20:26
  • 1
    You lose much quality if you downscale from 100% to 25% in one single step. Downsizing in 2+ steps will keep you from losing as much quality. Whether you scale pixels (an image) up or down, you will lose some quality. The 2+ step solution just loses less quality during scaling. ;=) – markE Apr 17 '14 at 20:45
  • is there another method to get high quality while downscaling. With your proposed method I often get a very blur image? – Michael Apr 17 '14 at 21:19
  • 1
    Really--I have better experiences with this method? Perhaps use one of the answers on your previous downscale question and then use that downscaled canvas to create a Kinetic.Image: http://stackoverflow.com/questions/18922880/html5-canvas-resize-downscale-image-high-quality – markE Apr 17 '14 at 21:40
  • Okay I will do it. Thank you! – Michael Apr 17 '14 at 21:47