2015-09-05 71 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

相關問題