大图模糊 canvas,小图清晰

Fuzzy image on large canvas, but crisp on small

我有一个应用程序,我想在隐藏的 canvas 上绘制一些图形,然后将其标记在我想要的任意多个位置,而不是多次绘制相同的图形(以获得更好的性能) . 目前可以在浮点坐标上绘制图形,同样适用于冲压。 在浮点坐标上绘制图像效果很好:图像清晰锐利。但是当我将图像从其他 canvas 复制到相同的浮点坐标时,我得到了模糊的图像。 更有趣的是:只有当目标 canvas 有大 width/height! 时才会模糊 当目标很小 (~20 px) 时,生成的图像很清晰(在Chrome)。 所以,我的问题:

  1. 为什么在目的地 canvas 很大的情况下我会得到模糊的图像
  2. 我该如何解决或解决这个问题?

这是演示 URL:http://the-coderok.azurewebsites.net/canvas.html 及其代码:它有 4 canvas。来源是我画图的地方,然后我会在休息时标记 3.

blurrySmall - small canvas,我在浮点坐标处复制图像。它产生清晰的图像。

模糊 - 大 canvas,结果图像模糊。我在浮动坐标处绘制相同的图形 - 结果很清晰。

清晰 - 我将图像复制到 int 坐标 - 结果清晰。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset=utf-8>
  <meta name="viewport" content="width=620">
  <title>HTML5 Demo: Canvas</title>
</head>

<body>
  <button id='doDraw'>Draw</button>
  <br>
  <section>
    <canvas id ="source" width="14" height="14" ></canvas>
    <br>
    <hr/>
    <canvas id ="blurrySmall" width="20" height="20"  ></canvas>

    <br />
    <hr/>
    <canvas id ="blurry" width="839" height="839"  ></canvas>
    <br />
    <hr/>
    <canvas id ="sharp" width="839" height="839"  ></canvas>    
  </section>



  <script type="text/javascript">
    var btn = document.getElementById('doDraw');
    btn.onclick = function(ev){
      doDraw();
    };
    /*
    xTranslation = -56.669999999999995
    yTranslation = -589.3000000000001
    */

    function doDraw(){
      var mainCanvas = document.getElementById("source");
      var mainContext = mainCanvas.getContext("2d");
      mainContext.beginPath();
      mainContext.arc(7, 7, 5, 0, 2*Math.PI, true);
      mainContext.closePath();
      mainContext.lineWidth =2;
      mainContext.strokeStyle = "rgba(255,127,14,1)";
      mainContext.stroke();

      var sharpCanvas = document.getElementById("sharp");
      var sharpContext = sharpCanvas.getContext("2d");
      sharpContext.drawImage(mainCanvas, 1, 1);

      var blurryCanvas = document.getElementById("blurry");
      var blurryContext = blurryCanvas.getContext("2d");
      blurryContext.drawImage(mainCanvas, 1.67, 1.3);

      blurryContext.beginPath();
      blurryContext.arc(33.67, 33.3, 5, 0, 2*Math.PI, true);
      blurryContext.closePath();
      blurryContext.lineWidth =2;
      blurryContext.strokeStyle = "rgba(255,127,14,1)";
      blurryContext.stroke();

      var blurrySmallCanvas = document.getElementById("blurrySmall");
      var blurrySmallContext = blurrySmallCanvas.getContext("2d");
      blurrySmallContext.drawImage(mainCanvas, 1.67, 1.3);
    }
  </script>
</body>

</html>

您绘制的图像变成位图。位图由像素组成,并且取决于分辨率。因此,每个像素将根据您复制它的位置放大或缩小。结果是复制到比原始位图大的位图会导致一些放大的伪像。即在这种情况下图像模糊。

要解决至少以最大 canvas 的分辨率渲染隐藏图像,它将被复制到,并且只按比例缩小。

我可以使用 CanvasRenderingContext2D.imageSmoothingEnabled 解决这个问题 https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled