Resizing a canvas image without blurring it
Check this fiddle: http://jsfiddle.net/yPFjg/
It loads the image into a canvas, then creates a resized copy and uses that as sprite.
With few modifications, you can implement an image loader that resizes images on the fly.
var ctx = document.getElementById('canvas1').getContext('2d');
var img = new Image();
var original = document.createElement("canvas");
var scaled = document.createElement("canvas");
img.onload = function() {
var oc = original.getContext('2d');
var sc = scaled.getContext('2d');
oc.canvas.width = oc.canvas.height = 16;
sc.canvas.width = sc.canvas.height = 32;
oc.drawImage(this, 0, 0);
var od = oc.getImageData(0,0,16,16);
var sd = sc.getImageData(0,0,32,32);
for (var x=0; x<32; x++) {
for (var y=0; y<32; y++) {
for (var c=0; c<4; c++) {
// you can improve these calculations, I let them so for clarity
sd.data[(y*32+x)*4+c] = od.data[((y>>1)*16+(x>>1))*4+c];
}
}
}
sc.putImageData(sd, 0, 0);
ctx.drawImage(scaled, 0, 0);
}
img.src = document.getElementById('sprite').src;
Some notes about getImageData: it returns an object with an array. The array has a height*width*4 size. The color components are stored in RGBA order (red, green, blue, alpha, 8 bits each value).
Simply turn off canvas' anti-aliasing for images - unfortunately this property is still vendor prefixed so here are the variations:
context.webkitImageSmoothingEnabled = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
then draw the image.
Optionally for older versions and browsers which hasn't implemented this yet, you can use CSS instead:
canvas {
image-rendering: optimizeSpeed; // Older versions of FF
image-rendering: -moz-crisp-edges; // FF 6.0+
image-rendering: -webkit-optimize-contrast; // Webkit (non standard naming)
image-rendering: -o-crisp-edges; // OS X & Windows Opera (12.02+)
image-rendering: crisp-edges; // Possible future browsers.
-ms-interpolation-mode: nearest-neighbor; // IE (non standard naming)
}
ONLINE TEST HERE