Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nearest Neighbor rendering in Canvas

I have a sprite that animates using a sprite sheet. He is only 16x16, but I want to scale him up to around 64x64 in all its pixel-y goodness!

alt text

The results are terrible, of course the browser is anti aliasing it. :/

Thanks!

EDIT: No css needed, here is my draw function.

function drawSprite(offsetx:number,offsety:number,posx:number,posy:number){
    ctx.drawImage(img, offsetx*32, offsety*32, 32, 16, posx*32, posy*8, 128, 32);
}

See it kinda working here (codepen)

like image 332
DevEarley Avatar asked Jul 21 '10 20:07

DevEarley


1 Answers

In case someone ever stumbles upon this again (like me), Webkit supports a -webkit-optimize-contrast value for image-rendering, which (currently) is an implementation of the nearest neighbor upscaling. It can be applied to both images and canvases.

Here's an example of how it goes.

.nn128 {
    width: 128px;
    height: 128px;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
}

<canvas class="nn128" width="16" height="16"></canvas>
<img src="path/to/small/image.png" alt="Small image" class="nn128">

With this setup, both WebkitSafari and Gecko/Firefox will enlarge the 16x16 canvas space and the small image to 128x128 with the nearest neighbor algorithm.

UPDATE The answer initially stated that Webkit browsers supported this; in fact, as of 2011-12-24, it works with Safari on Mac OS and Chrome on Mac OS, but not with Chrome one Windows (Safari on Windows was not verified), as stated on Issue 106662 of the Chromium bug tracker. Lexically, Chrome on Windows will accept the -webkit-optimize-contrast value in a CSS style sheet, but it won't have any effect. It is my expectation that it will work someday, and this method will be the right way to get nearest neighbor upscaling, but for now, using this method means Windows Chrome users will have to live with the blurriness.

like image 154
zneak Avatar answered Sep 20 '22 14:09

zneak