I know this has already been answered, but I want to give more information to talk about what's going on here and what can be done.
This is because of image smoothing, which defaults to smooth algorithms like bilinear/trilieaner/bicubic on canvas by default, whereas what you want is known as nearest-neighbor.
The specification has recently added a property called imageSmoothingEnabled
, which defaults to true
and determines if images drawn on non-integer coordinates or drawn scaled will use a smoother algorithm. If it is set to false
then nearest-neighbor is used, producing a less smooth image and instead just making larger looking pixels.
Image smoothing has only recently been added to the canvas specification and isn’t supported by all browsers, but some browsers have implemented vendor-prefixed versions of this property. On the context there exists mozImageSmoothingEnabled
in Firefox and webkitImageSmoothingEnabled
in Chrome and Safari, and setting these to false will stop anti-aliasing from occurring. Unfortunately, at the time of writing, IE9 and Opera have not implemented this property, vendor prefixed or otherwise.
In general you simply need to follow two rules:
- If you are scaling the canvas, you need to disable image smoothing or scale it by using nearest-neighbor interpolation. There are a few algorithms to do this manually right now and this is what the above options are doing.
- If you are not drawing on integer coordinates you'll get the same problem and it has the same solution. If the above options do not exist on your browser you'll need to revert to integer coordinates
(x | 0, y | 0)
Where x | 0
floors x
quickly, however will not work with numbers larger than 2,147,483,647: The largest 32 bit signed integer.
Hopefully your coordinates are not larger than that!