1

I set imageSmoothingEnabled to false on my drawing context to get sharp pixel rendering when I draw to the canvas, but for some reason the image comes out blurry. The example below sets up a 20x20 canvas filled with black and draws a red diagonal line of pixels with imageSmoothingEnabled set to false across it. It still comes out blurry in Chrome, FF, and Edge.

Can anyone tell me why this isn't working and how to fix it?

HTML:

<canvas></canvas>

JS:

var context = document.querySelector('canvas').getContext('2d');

context.canvas.height = context.canvas.width = 20;

context.fillStyle = "#000000";
context.fillRect(0, 0, 20, 20);

context.imageSmoothingEnabled = false;
context.fillStyle = "#ff0000";

for (var i = 0; i < 20; i ++) {

  context.fillRect(i, i, 1, 1);

}

I have set up the following fiddle to showcase my problem:

https://jsfiddle.net/ct39rqpf/7/

Note: In the fiddle, you can set the CSS to have image-rendering:pixelated for the canvas and it will show what I'm trying to get with imageSmoothingEnabled set to false.

EDIT: I found that imageSmoothingEnabled only applies when scaling an image, which I am not doing. What I don't understand is that when I apply image-rendering:pixelated in the CSS, I get a much crisper image than I do simply by drawing pixels to the unscaled canvas. Why is there a blur by default?

Frank
  • 2,050
  • 6
  • 22
  • 40
  • **image**SmoothingEnabled has effect only on image sources (drawImage and CanvasPatterns). But anyway your problem is that you do stretch your canvas with CSS. So there will be antialiasing set by the renderer, which you do disable with that "pixelated" rule. – Kaiido Jan 12 '20 at 23:34
  • I'm starting to think that this is a problem with my screen resolution, which is why `image-rendering:pixelated` removes the blur and by default there is blur when drawing unscaled images or using `fillRect`. – Frank Jan 12 '20 at 23:39
  • By default there is no blur, you fill rects at pixel boundaries, no reason for any antialiasing. **But** by default your canvas is a 20x20px image. Since you do stretch it, there is antialiasing kicking in. – Kaiido Jan 12 '20 at 23:43
  • @Kaiido There is no anti-aliasing in the canvas (note that he is rendering to pixel boundaries). The blurring is the result of DOM compositing applying bi-linear smoothing to the canvas that can be prevented via `image-rendering:pixelated` – Blindman67 Jan 12 '20 at 23:50
  • @Blindman exactly what I said yes ;-) – Kaiido Jan 12 '20 at 23:51
  • @Kaiido not really you said *"...there is antialiasing kicking in"* which is very different than smoothing. – Blindman67 Jan 12 '20 at 23:52
  • ... what OP experiences is antialiasing artifact, caused by "stretching" their canvas through CSS, which is triggered by "the renderer". But yes "By default there is no blur". – Kaiido Jan 12 '20 at 23:55
  • 1
    The width and height in CSS did cause some blur, but I had blur without CSS scaling. My problem was that my Display Settings in Windows 10 were set to scale everything to 175% of the true resolution. After setting my resolution to 100% scale, I could literally see each pixel on the screen filled in perfectly with the color that was supposed to be there without any blur. This was 100% user error. Wasted 3 hours trying to figure out what was going on here... My own settings were to blame. – Frank Jan 12 '20 at 23:57
  • I think `image-rendering:pixelated` takes your system resolution settings into consideration to render a crisp image on the screen. My browser window wasn't scaled up, but my entire Windows explorer was, which caused quite a bit of blur. What I couldn't figure out was how `image-rendering:pixelated` was getting around this but drawing with nothing scaled was producing a blur. Again, it was my own Windows Display Settings... – Frank Jan 13 '20 at 00:09

0 Answers0