2013-02-23 34 views
0

我正在編寫一個Chrome擴展程序,用於阻止可能令人反感的內容。我正在實施的一種方法是掃描所有圖像並查看顯示的皮膚數量。我創建了一個新的圖像對象,將crossOrigin標誌設置爲「」,然後創建一個onload函數,將圖像繪製到畫布上,從畫布中讀取數據,然後執行分析,爲調用函數設置一個布爾標誌。在定義onload函數後,我從網頁的源列表中爲我的圖像節點分配一個src。 image_scanner函數在for循環中調用,循環遍歷網頁上的每個圖像節點並執行各種操作以阻止。這是我執行的最後一項操作。這裏是調用image_scanner代碼:Chrome擴展程序img.onload函數連續執行

   if (image_scanner(options.scanner_sensitivity, images[i])) 
       { 
       // Replace the image with a blank white image 
       images[i].src = chrome.extension.getURL("replacement.png"); 


       } 

這裏是image_scanner功能

function image_scanner(sensitivity, image) 
    { 
     // Sensitivity is a number and image is an image node. 

     // Declare a variable to count the number of skin pixels 
     var skin_count = 0; 

     if (image.width == 0 && image.height ==0) 
     { 
     // This means the image has no size and we cannot block it. 
     return false; 
     } // end if 


     var return_value = null; // set bool flag 
     // Create an HTML5 canvas object. 
    var canvas = document.createElement('canvas'); 

     //window.alert("Created Canvas."); // used for testing. 

     // Get the context for the canvas. 
     var context = canvas.getContext("2d"); // This is what we actually use to draw images and pull the data from them. 

     context.canvas.width = image.width; // Set the canvas width to the width of the image 
     context.canvas.height = image.height; // Set the canvas height to the height of the image 


     img = new Image(); // Create a new image node to circumvent cross-domain restrictions. 
     img.crossOrigin = " "; // Set crossOrigin flag to ' ' so we can extract data from it. 

     img.onload = function(){ 
      window.alert(img.src); // This always gives the same src until Chrome ends the function 
      context.drawImage(this, 0,0); // Draw the image onto the canvas. 

      var pixels = context.getImageData(0, 0, image.width, image.height).data; 


      // Now pixels is an array where every four entries in the array is the RGBa for a single pixel. 
      // So pixels[0] is the R value for the first pixel, pixels[1] is the G value for the first pixel, 
      // pixels[2] is the B value for the first pixel, and pixels[3] is the a (alpha or transparency) value for the first pixel. 

      // This means that pixels.length/4 is the number of pixels in the image. 
      // Now we calculate the number of skin pixels we can have before blocking the image. 
      var limit = ((pixels.length)/4) * (sensitivity/100); 

      // Now we go through the array of pixel data, checking if each pixel is a skin colored pixel based on its RGB value (the first 3 entries for that pixel in the pixels array) 
      // Each time we find a skin colored pixel, we increment skin_count and check if skin_count >= limit. If so, we return true. 
      for (var i = 0; i < pixels.length; i += 4) // We go up by four since every four entries describes 1 pixel 
      { 

      // pixel is skin if 0 <= (R-G)/(R+G) <= .5 and B/(R+G) <= .5 pixels[i] is the R value, pixels[i+1] is the G value, and pixels[i+2] is the B value. 
      if ((0 <= ((pixels[i] - pixels[i+1])/(pixels[i] + pixels[i+1]))) && (((pixels[i] - pixels[i+1])/(pixels[i] + pixels[i+1])) <= 0.5) && ((pixels[i+2]/(pixels[i] + pixels[i+1])) <= 0.5)) 
      { 
       skin_count++; 
       //window.alert("Found skin pixel."); // used for testing. 

       if (skin_count >= limit) 
       { 
        //window.alert("Blocking image with src: " + image.src); // used for testing. 
        img.onload = null; // try to clear the onload function 
        return_value = true; 
        return false; 
       } // end inner if 
      } // end outer if 
      } // end for loop 

     //var temp; 
     img.onload = null; 
     return_value = false; 
     return false; 

     }; // end onload function 


    img.src = image.src; // Set the new image to the same url as the old one.  



    return return_value; 
} // end image_scanner 

我不知道是什麼問題,但在onload功能將運行,經過像素,設置該標誌,返回,然後再次運行。我試過在Chrome的調試器中進行調試,這就是我能找到的。我已經嘗試在onload函數中將onload設置爲null,但它不起作用。我試着從onload函數返回false。我試過在image_scanner函數中等待,直到return_value!= null,但似乎進入了一個無限循環,我從來沒有從onload函數獲得警報。如果有人知道爲什麼onload函數會重複執行,我將非常感激。

回答

0

如果你要設置.src空白圖像,不想.onload來再次調用時加載,那麼你應該清楚.onload設置.src之前。

if (image_scanner(options.scanner_sensitivity, images[i])) { 
    // clear our onload handler 
    images[i].onload = function() {}; 
    // Replace the image with a blank white image 
    images[i].src = chrome.extension.getURL("replacement.png"); 
} 

它也像你返回從onload句柄值並期望價值得到從image_scanner函數返回。它不這樣工作。 onload處理程序會在一段時間後調用很長時間,在image_scanner已經返回之後很久。您需要重寫代碼才能使用onload的異步處理。

+0

我試過了,但沒有奏效。如果您注意到,函數image_scanner在if語句中被調用,因爲它返回一個布爾值。它位於image_scanner的內部,我創建了一個新的圖像對象,並給它重複的onload函數。 – DragonSlayer 2013-02-23 18:01:11

+0

@DragonSlayer - 查看我添加到我的答案中的第二個問題。 'onload'是異步的(在image_scanner()''返回後調用很長時間,所以你不能像你試圖做的那樣同步使用它。 – jfriend00 2013-02-23 20:53:32

+0

如果我在onload處理程序中放置一個bool標誌,然後在那之後放一個while循環在布爾標誌由onload處理程序設置之前什麼都不會做, – DragonSlayer 2013-02-24 15:45:57