Matt
Matt

Reputation: 273

Why does the HTML Canvas image appear pixelated?

Problem

I've placed the same image (Netflix) using simple HTML vs using Canvas, and the Canvas version is a lot more pixelated that the simple tag version.

What I've tried


Please let me know if you have any idea how I could fit it!

window.onload = () => {
  var dpi = window.devicePixelRatio;
  var canvas = document.getElementById("myCanvas");
  var context = canvas.getContext("2d");
  var imgLogo = document.getElementById("logo");
  context.imageSmoothingEnabled = false;
  context.drawImage(imgLogo, 0, 0, 175, 98.438);
}
.hidden {
  display: none;
}
<img class = "hidden" id = "logo" src = "https://assets.stickpng.com/images/580b57fcd9996e24bc43c529.png" width="200"/>


<canvas id = "myCanvas" height = "150" width = "500">
 </canvas>
 
 
<div class="blend1">
  <div id="logoContainer">
    <img src="https://assets.stickpng.com/images/580b57fcd9996e24bc43c529.png" width="175" />
  </div>
</div>

Upvotes: 3

Views: 1652

Answers (2)

Nico
Nico

Reputation: 1

This is a follow-up to Andrew's answer. I believe this works better:

var valueX = imgLogo.naturalWidth; var valueY = imgLogo.naturalHeight;

Upvotes: 0

Andrew
Andrew

Reputation: 7880

After quite some research, I finally came across a very simple solution. I wonder why it was so hard to find. It's as simple as this:

context.imageSmoothingQuality = "high";

So with the following, you should get two equally smooth logos:

window.onload = () => {
  var canvas = document.getElementById("myCanvas");
  var context = canvas.getContext("2d");
  var imgLogo = document.getElementById("logo");

  // Only set this value
  var valueX = 256;

  var valueY = valueX / 16 * 9;
  imgLogo.width = valueX;
  canvas.width = valueX;
  canvas.height = valueY;
  context.imageSmoothingQuality = "high"; // or "low" or "medium"
  context.drawImage(imgLogo, 0, 0, valueX, valueY);
}
.hidden {
  display: none;
}
<img class = "hidden" id = "logo" src = "https://assets.stickpng.com/images/580b57fcd9996e24bc43c529.png" width="200"/>


<canvas id = "myCanvas" height = "150" width = "500">
 </canvas>
 
 
<div class="blend1">
  <div id="logoContainer">
    <img src="https://assets.stickpng.com/images/580b57fcd9996e24bc43c529.png" width="175" />
  </div>
</div>

Source.

Some also recommend drawing in a hidden bigger canvas and then re-drawing each time halving the picture, but I think this solution is already good enough, and obviously much more simple.

PS 1: apparently it only works on Chromium-based browsers. If you want to support other browsers, you might need to do what the link above details.

PS 2: Check browser support for imageSmoothingQuality.

Upvotes: 6

Related Questions