HTML5 - Canvas, drawImage () draws an image blurry

I am trying to draw the next image on the canvas, but it looks blurry, despite determining the size of the canvas. As you can see below, the image is crisp and sharp, while on the canvas it is blurry and pixelated.

enter image description here

and this is how it looks (the left one is the original, and the right one is a painted canvas and blurred).

enter image description here

What am I doing wrong?

console.log('Hello world') var c = document.getElementById('canvas') var ctx = c.getContext('2d') var playerImg = new Image() // http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image playerImg.src = 'http://i.imgur.com/ruZv0dl.png' playerImg.width = 32 playerImg.height = 32 playerImg.onload = function() { ctx.drawImage(playerImg, 0, 0, 32, 32); }; 
 #canvas { background: #ABABAB; position: relative; height: 352px; width: 512px; z-index: 1; } 
 <canvas id="canvas" height="352" width="521"></canvas> 

+13
source share
6 answers

The reason for this is due to Anti Aliasing. Just set imageSmoothingEnabled as false

 context.imageSmoothingEnabled = false; 

Here is jsFiddle verson

jsFiddle: https://jsfiddle.net/mt8sk9cb/

 var c = document.getElementById('canvas') var ctx = c.getContext('2d') var playerImg = new Image() // http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image playerImg.src = 'http://i.imgur.com/ruZv0dl.png' playerImg.onload = function() { ctx.imageSmoothingEnabled = false; ctx.drawImage(playerImg, 0, 0, 256, 256); }; 
+20
source

Your problem is that your css canvas{width:512} restrictions canvas{width:512} and the canvas width=521 property will force your browser to reprogram the entire canvas.

To avoid this, remove these css declarations.

 var c = document.getElementById('canvas') var ctx = c.getContext('2d') var playerImg = new Image() // http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image playerImg.src = 'http://i.imgur.com/ruZv0dl.png' playerImg.width = 32 playerImg.height = 32 playerImg.onload = function() { ctx.drawImage(playerImg, 0, 0, 32, 32); }; 
 #canvas { background: #ABABAB; position: relative; z-index: 1; } 
 <canvas id="canvas" height="352" width="521"></canvas> 

Also, if you oversamble the image (from 32x32 to another size), @canvas's solution would be correct.

+12
source

The following code works for me:

 img.onload = function () { canvas.width = img.width; canvas.height = img.height; context.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height); }; img.src = e.target.result; // your src 
+1
source

In addition to @canvas answer.

 context.imageSmoothingEnabled = false; 

It works great. But in my case, when resizing the canvas, this property returns to true.

 window.addEventListener('resize', function(e){ context.imageSmoothingEnabled = false; }, false) 
+1
source

Since I came across this earlier post on some of my problems, there is even more understanding of blurry images to overlay on top of the 'imageSmoothingEnabled' solution.

This is more specific for the case of rendering for a specific monitor, and only some people encountered this problem if they tried to render graphics with retina quality on canvas with disappointing results.

In essence, high-density monitors mean that your canvas needs to consider this extra pixel density. If you do nothing, canvas will only display enough pixel information in its context to allow for a pixel ratio of 1.

Therefore, for many modern monitors that have coefficients> 1, you must change your canvas context to take into account this additional information, but keep your canvas normal width and height.

To do this, you simply set the width and height of the rendering context to: target width and height * window.devicePixelRatio.

 canvas.width = target width * window.devicePixelRatio; canvas.height = target height * window.devicePixelRatio; 

Then you set the canvas style so that the canvas size matches the normal sizes:

 canvas.style.width = '${target width}px'; canvas.style.height = '${target height}px'; 

The last time you display an image with the maximum context size that the image allows. In some cases (for example, when rendering images in SVG format), you can still get the best image quality by visualizing an image with pixel dimensions:

 ctx.drawImage( img, 0, 0, img.width * window.devicePixelRatio, img.height * window.devicePixelRatio ); 

So, to show this phenomenon, I made a violin. You will NOT see differences in canvas quality if you use a pixelRatio monitor close to 1.

https://jsfiddle.net/ufjm50p9/2/

0
source

Simple tip: draw .5 in x and y. e.g. drawImage (, 0.5, 0.5): D There you get clear edges: D

-3
source

All Articles