【问题标题】:Why does the HTML Canvas image appear pixelated?为什么 HTML Canvas 图像出现像素化?
【发布时间】:2021-03-26 14:57:58
【问题描述】:

问题

我使用简单的 HTML 和使用 Canvas 放置了相同的图像 (Netflix),Canvas 版本比简单标签版本像素化程度更高。

我的尝试

  • 我已尝试更改画布的比例并设置 window.pixelDeviceRatio = 2,它确实略有改善,但似乎仍然像素化。
  • 我也尝试设置context.imageSmoothingEnabled= false,但这并没有改变任何东西。
  • 设置context.smoothImageQuality = high查看下面的照片以了解其外观

如果您知道如何安装它,请告诉我!

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>

【问题讨论】:

  • 抱歉,究竟什么是像素化?我觉得很好。你试过this onethis one吗? (更多水印但更大的测试)
  • 谢谢@Andrew,我指的是像素化的图像是“Netflix”标志。如果你放大到我的小提琴中的顶部版本,你会发现线条不像我的小提琴中的低版本那样平滑
  • 哦,我认为您不是在谈论像素化,而是在谈论混叠。显然,浏览器的默认图像渲染器具有比 drawImage 更好的抗锯齿算法,因为您正在使用它。也许有一些设置可以尝试不同的方法?顺便说一句,imgLogo 实际上是背景,反之亦然。我认为如果您删除沙发图片并仅在白色背景上测试 Netflix 徽标,它会更明显。不确定这是否有帮助,但something to try.
  • 感谢您指出您的解释有很大帮助,这是更新后的小提琴 - jsfiddle.net/gqjznLwu - 我也会更新我的帖子。我尝试了您发送的链接,但不幸的是它并没有改变任何东西。
  • 好吧,我做了一些研究,但找不到正确的答案。 Here's something。 FWIW,我已经简化了你的小提琴,只使用一个 img 并使用一个变量来设置两个徽标的大小。 Link.

标签: html css html5-canvas


【解决方案1】:

经过一番研究,我终于找到了一个非常简单的解决方案。我想知道为什么这么难找到。就这么简单:

context.imageSmoothingQuality = "high";

因此,通过以下方式,您应该得到两个同样平滑的徽标:

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 在隐藏的更大画布中绘制,然后每次将图片减半时重新绘制,但我认为这个解决方案已经足够好了,而且显然要简单得多。

PS 1:显然它只适用于基于 Chromium 的浏览器。如果您想支持其他浏览器,您可能需要按照上面的链接进行操作。

PS 2: Check browser support for imageSmoothingQuality.

【讨论】:

  • 嗯,你用的是什么浏览器?我刚刚在 Chrome 87 上尝试过,它仍然很模糊。我添加了我在更新问题中看到的屏幕截图。 Lmk 你正在使用的原因可能只是我的问题!再次感谢所有帮助
  • 哇,我从来没有拍过那张模糊的照片。您的浏览器是否处于 100% 缩放?它看起来像是放大了(第一个版本具有固定分辨率,第二个版本由浏览器实时处理)。我试过 Opera 和 Vivaldi(都基于 Chromium),所以 Chrome 应该是完全一样的。
  • 我从 fiddle 截取了一张屏幕截图,这里是你在 Fiddle 中的代码的链接 - jsfiddle.net/7q10yg8k - 如果这里对你来说很模糊,请点击 lmk。如果不是,那很可能是我的问题!
  • 但是在your screenshot(现已消失)中,徽标要大得多,就像您的浏览器被缩放一样。 This is how I see itthis is if I zoom in to 250%。使用Ctrl+0,您应该将缩放恢复为 100%。你试过其他浏览器吗?
  • 有效!谢谢安德鲁,你说得对,我只是放大了太多。感谢所有帮助?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
相关资源
最近更新 更多