Search code examples
javascriptjquerygoogle-chromepixelimage-scaling

How to resize an image with JavaScript / jQuery without pixelation like the browser does?


I'm making a javascript / jquery program for a webpage to let a user open an image file locally from their computer, and then the program resizes it to a 16 x 16 icon size and saves it as a data url.

Everything works fine, except the resized image is very pixelated. I currently am taking the local image file, and making a data url from it. Then creating a 16 x 16 canvas element, and then drawing the image onto the canvas, and making a new data url from that.

I would like some different way to do it, as the newly resized image is very pixelated and not smooth, and does not seem anti-aliased. When the browser displays the original image with the width and height attributes set to 16, it looks very nice and smooth. This is what I would like. I don't understand how to get the same result as what is displayed when the browser does it. I am using Google Chrome.

I made a small example of it here: http://jsfiddle.net/5Pj8m/

In the example I used the jsFiddle logo, although you could test it with any local file, and see the results. Maybe this code can help someone else learn how to do it, but still, I think the resulting resize image could or should look much better!

I hope I have explained what I am trying to do, and that it is somehow possible. Can anyone help me or figure this out?

Here is the code.

HTML:

<input type='file' id='inputFile'>
<table border=1><tr><td>
<span id='spanDisplayOrigFull'>OrigFull:
<img src=http://doc.jsfiddle.net/_images/jsfiddle-logo-thumb.png>
</span>
</td><td>
<span id='spanDisplayOrigIcon'>OrigIcon:
<img src=http://doc.jsfiddle.net/_images/jsfiddle-logo-thumb.png width='16' height='16'>
</span>
</td></tr><tr><td>
<span id='spanDisplayNewFull'>NewFull: </span>
</td><td>
<span id='spanDisplayNewIcon'>NewIcon: </span>
</td></tr></table>

JAVASCRIPT:

$('#inputFile').bind('change', function()
{

var file = inputFile.files[0];

var reader = new FileReader();
reader.readAsDataURL(file);

reader.onload = function()
{

var imageUrlFull = reader.result;

var imageLocalFull = new Image();
imageLocalFull.src = imageUrlFull;
imageLocalFull.id = 'imageLocalFull';

imageLocalFull.onload = function()
{

var canvas = document.createElement('canvas');
canvas.width = 16; canvas.height = 16;

var context = canvas.getContext('2d');
context.drawImage(imageLocalFull, 0, 0, 16, 16);

var imageUrlIcon = canvas.toDataURL(file.type);

var imageLocalIcon = new Image();
imageLocalIcon.src = imageUrlIcon;
imageLocalIcon.id = 'imageLocalIcon';

imageLocalIcon.onload = function()
{

spanDisplayNewFull.appendChild(imageLocalFull);
spanDisplayNewIcon.appendChild(imageLocalIcon);

};

};

};

});

Solution

  • Well, from your code it looks like the image scaling job is actually left to your browser's implementation, so I think you're going to have varying results with different browsers. Some might smooth it, some might not.

    I see two ways to go about trying to tackle this problem. One way is to use active content, such as a Java applet/Flash or to use an actual back-end to do the scaling. I.e. you receive the file, send it to a server and the server returns the scaled-down image, as most image scaling sites do.

    The second way is to try HTML5 and implement a down-scaling algorithm yourself. The best I can do there for guidance is point you to this and this as a starting point.

    Sorry if that doesn't help.