2

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

  • I've tried changing the scale of the Canvas and setting the window.pixelDeviceRatio = 2 and it does improve it slightly, but still seems pixelated.
  • I've also tried setting context.imageSmoothingEnabled= false, but that didn't change anything.
  • Setting the context.smoothImageQuality = high, check the photo below to see how that looks

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>
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
Matt
  • 233
  • 1
  • 2
  • 12
  • Sorry, but what is exactly pixelated? It looks fine to me. Have you tried [this one](https://thumbs.dreamstime.com/b/sofa-brickwall-24698788.jpg) or [this one](https://thumbs.dreamstime.com/z/sofa-front-brick-wall-25528836.jpg)? (more watermark but bigger for testing) – Andrew Dec 15 '20 at 23:07
  • Thanks @Andrew, the image I'm referring to that's pixelated is the "Netflix" logo. If you zoom in to the top version in my fiddle, you'll see the lines are not nearly as smooth as in the lower version in my fiddle – Matt Dec 15 '20 at 23:16
  • Oh, I think you are not talking about pixelation but about aliasing. Apparently the browser's default image renderer has a better antialiasing algorithm than `drawImage` as you are using it. Maybe there is some setting to try different approaches? BTW, `imgLogo` is actually the background and the other way around. I think it's more noticeable if you remove the sofa pic and just test the Netflix logo over a white background. Not sure if this helps, but [something to try](https://stackoverflow.com/questions/4261090/html5-canvas-and-anti-aliasing). – Andrew Dec 15 '20 at 23:23
  • Thanks for pointing that out your explanation helped a lot, here is the updated fiddle - https://jsfiddle.net/gqjznLwu/ - I will update my post as well. I tried the link you sent but unfortunately it does not change anything. – Matt Dec 15 '20 at 23:31
  • Well, I did some research but couldn't find a proper answer. [Here's something](https://www.xspdf.com/resolution/50518085.html). FWIW, I have simplified your fiddle, using just one `img` and using a variable to set the size of both logos. [Link](https://jsfiddle.net/u2dg5wm1/). – Andrew Dec 16 '20 at 00:08
  • @Andrew just tried everything in that article and still doesn't work Thanks a ton for the help though, really appreciate it. I'll keep trying things – Matt Dec 16 '20 at 00:44

1 Answers1

4

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.

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
Andrew
  • 7,602
  • 2
  • 34
  • 42
  • Hmm what browser are you using? I just tried on Chrome 87 and it's still blurry. I added a screenshot of what I see in the updated question. Lmk what you're using cause that might just be a problem on my end! And thanks again for all the help – Matt Dec 16 '20 at 13:31
  • Wow, I never got that blurry picture. Is your browser at 100% zoom? It looks like it's zoomed (the first version has a fixed resolution, the second one is handled by the browser in real-time). I tried on Opera and Vivaldi (both Chromium based), so Chrome should be exactly the same. – Andrew Dec 16 '20 at 14:00
  • I took a screenshot from fiddle, here's the link to your code in Fiddle - https://jsfiddle.net/7q10yg8k/ - lmk if it's blurry here for you. If it isn't then it's most likely a problem on my end! – Matt Dec 16 '20 at 14:36
  • But in [your screenshot](https://i.stack.imgur.com/9RhJe.png) (now gone) the logo was much bigger, like if your browser was zoomed. [This is how I see it](https://i.imgur.com/TCPmtn0.png), and [this is if I zoom in to 250%](https://i.imgur.com/E4thTDy.png). With `Ctrl+0` you should restore the zoom to 100%. Did you try other browsers? – Andrew Dec 16 '20 at 15:53
  • 1
    It works! Thanks Andrew, you were right that I was just zooming in too much. Appreciate all the help – Matt Dec 17 '20 at 14:25
  • Even more than a year later, I see that it does smooth nicely in Chrome -but not in Firefox. – bob.mazzo Feb 28 '22 at 16:05
  • Right, as per caniuse.com (mentioned in the PS), it's still not supported by Firefox, what a pity. – Andrew Feb 28 '22 at 22:35