2015-09-05 70 views
0

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

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

你有没有调试过你的代码,找出具体的问题在哪里? – PeeHaa

+1

在尝试修改画布,将数据获取和灰度移动到加载回调之前,这看起来像图像可能尚未加载 –

回答

2

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

  1. 您需要设置.onload处理程序,然后设置.src属性。当图像已经在浏览器缓存中时,图像在设置.src属性的那一刻被加载。当图像已经加载时设置onload处理程序什么都不做。
  2. 你所得到的图象 - 并调用greyscale() -function没有如果已经执行了.onload处理程序检查,所以当图像缓存,你的灰阶功能将在onload处理程序之前执行可能提请图像画布。如果要确保在绘制图像后执行了灰度转换代码,请在ctx.drawImage(img, 0, 0);之后将该代码移入加载处理程序。
  3. greyscale函数中,当您设置imageData.data时,将i与4相乘,但在读取数据时不会。这意味着你写的比你读的其他像素。您已经在for循环中将i增加了4,因此不需要乘法。
  4. 您正在从远程域加载图像(mdn.mozillademos.org)。当您将远程图像绘制到画布上时,画布会变得“受到交叉来源数据的污染”,并且由于安全原因,某些功能(如getImageData)被禁用。将图像复制到脚本所在的同一个域中。 (感谢,@NiettheDarkAbsol)

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

+1

您错过了最大的问题:加载远程图像会污染画布,你不能在受污染的画布上调用'getImageData'。 –

+0

@NiettheDarkAbsol谢谢,我加了这个。 – Philipp

+0

非常感谢Phillipp,我终于可以使它工作。 – inSynergy

相关问题