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

时间:2015-09-05 20:31:51

标签: javascript html5 html5-canvas

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

<!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>

1 个答案:

答案 0 :(得分:2)

您的代码中只有一个错误。我们已经找到了4:

  1. 在设置.onload属性之前,您需要设置.src处理程序。当图像已经在浏览器缓存中时,在设置.src属性时加载图像。在已经加载图像时设置onload处理程序不会做任何事情。
  2. 您正在获取imagedata并调用greyscale() - 函数而不检查.onload处理程序是否已执行,因此当图像未被高速缓存时,你的灰度函数可能会在onload-handler将图像绘制到画布之前执行。如果要确保在绘制图像后执行灰度转换代码,请在ctx.drawImage(img, 0, 0);之后将该代码移动到onload-handler中。
  3. greyscale功能中,当您设置imageData.data时,您将i乘以4,但在阅读数据时则不会。这意味着你写的其他像素比你读的还要多。你已经在for循环中将i增加了4,因此不需要乘法。
  4. 您正在从远程域(mdn.mozillademos.org)加载图像。在将远程图像绘制到画布上的那一刻,画布变得被跨源数据污染了#34;出于安全原因,某些功能(如getImageData)已被禁用。将映像复制到脚本所在的同一域。 (谢谢@NiettheDarkAbsol)
  5. 顺便说一句:除非您将新创建的图像节点插入网站文档的DOM树中,否则new Image()不会显示在任何位置。您不必在代码中执行此操作。所以img.style.display = 'none';完全没必要。