您好,有人可以帮助 html5 灰度转换代码吗?

Hi can someone help in html5 grayscale conversion code?

我在这里找不到错误。我不知道我在哪里错过了一些没有让我的代码将图像转换为灰度的东西。如果有人可以尝试这段代码并帮助我找出问题,那将会很有帮助。

<!doctype html>
<html>
  <head>
    <title>Canvas API</title>
  </head>
  <body>
    <!-- In order to have canvas we need to use the canvas tag  -->
    <canvas id="c" width="500" height="500"></canvas>
    <!-- To use canvas we need to access is from javascript code -->
    <script>
      var c = document.querySelector("#c"); // grab a canvas with id="c"
      var ctx = c.getContext("2d"); // context in which we are using it

      var img = new Image();
      img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';

      img.onload = function() {
        ctx.drawImage(img, 0, 0);
        img.style.display = 'none';
      };

      var myData = ctx.getImageData(0,0, 500, 500);
      console.log(myData);



      var grayscale = function(imageData) {
        var numPixels = imageData.data.length;
        for (var i = 0; i < numPixels; i+=4) {
          var avg = 0.34 * imageData.data[i] + 0.5 * imageData.data[i + 1] + 0.16 * imageData.data[i + 2];
          imageData.data[i*4+0] = avg;
          imageData.data[i*4+1] = avg;
          imageData.data[i*4+2] = avg;
          // imageData.data[i*4+3] = 255;
        }
        ctx.putImageData(imageData, 0, 0);
      };

      grayscale(myData);

    </script>
  </body>
</html>

您的代码中不止一个错误。我们已经找到 4:

  1. 您需要在设置 .src 属性之前设置 .onload 处理程序。当图像已经在浏览器缓存中时,将在设置 .src 属性时加载图像。在图像已加载时设置 onload 处理程序不会执行任何操作。
  2. 您正在获取图像数据并调用 greyscale() 函数而不检查 .onload 处理程序是否已经执行,因此当图像 不是 缓存,您的灰度函数可能会在 onload-handler 将图像绘制到 canvas 之前执行。如果您想确保在绘制图像后执行灰度转换代码,请将该代码移至 ctx.drawImage(img, 0, 0);.
  3. 之后的 onload-handler 中
  4. greyscale函数中,当您设置imageData.data时,您将i乘以4,但在读取数据时却没有。这意味着您写入的像素与读取的像素不同。您已经在 for 循环中将 i 递增 4,因此不需要乘法。
  5. 您正在从远程域 (mdn.mozillademos.org) 加载图像。当您将远程图像绘制到 canvas 时,canvas 变为 "tainted by cross-origin data" 并且某些功能(例如 getImageData 出于安全原因被禁用。将图像复制到脚本所在的同一域。 (谢谢,@NiettheDarkAbsol)

顺便说一句:除非您将新创建的图像节点插入到网站文档的 DOM 树中,否则 new Image() 不会在任何地方显示。你不会在你的代码中这样做。所以img.style.display = 'none';完全没有必要。