2011-09-21 149 views
3

我發現這個腳本將圖像轉換爲黑白圖像,效果很好,但我希望能夠更好地理解代碼。我以評論的形式將我的問題放在代碼中。瞭解畫布如何將圖像轉換爲黑白圖像

任何人都可以在一個小更詳細的解釋這裏發生了什麼:

function grayscale(src){ //Creates a canvas element with a grayscale version of the color image 
    var canvas = document.createElement('canvas'); 
    var ctx = canvas.getContext('2d'); 
    var imgObj = new Image(); 
    imgObj.src = src; 
    canvas.width = imgObj.width; 
    canvas.height = imgObj.height; 
    ctx.drawImage(imgObj, 0, 0); //Are these CTX functions documented somewhere where I can see what parameters they require/what those parameters mean? 
    var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height); 
    for(var y = 0; y < imgPixels.height; y++){ 
     for(var x = 0; x < imgPixels.width; x++){ 
      var i = (y * 4) * imgPixels.width + x * 4; //Why is this multiplied by 4? 
      var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3; //Is this getting the average of the values of each channel R G and B, and converting them to BW(?) 
      imgPixels.data[i] = avg; 
      imgPixels.data[i + 1] = avg; 
      imgPixels.data[i + 2] = avg; 
     } 
    } 
    ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height); 
    return canvas.toDataURL(); 
} 

回答

11
  1. 畫布功能,最喜歡的功能,an official specification描述。另外,MDC對更多「非正式」文章有幫助。例如。 MDC上的drawImage功能是here

  2. getImageData函數返回一個對象,該對象包含一個包含所有像素的字節數據的數組。每個像素由4個字節描述:r,g,ba

    r,gb是顏色成分(紅色,綠色和藍色),alpha是不透明度。所以每個像素使用4個字節,因此像素的數據從pixel_index * 4開始。

  3. 是的,它的平均值。因爲在接下來的3行rgb都設置爲相同的值,所以每個像素都會獲得灰色(因爲所有3個組件的數量都是相同的)。

    所以基本上,對於所有像素,這將保持:r === g,g === b,因此也r === b。這種顏色爲灰色(0, 0, 0爲黑色,255, 255, 255爲白色)。

8
function grayscale(src){ //Creates a canvas element with a grayscale version of the color image 
    //create canvas 
    var canvas = document.createElement('canvas'); 
    //get its context 
    var ctx = canvas.getContext('2d'); 
    //create empty image 
    var imgObj = new Image(); 
    //start to load image from src url 
    imgObj.src = src; 
    //resize canvas up to size image size 
    canvas.width = imgObj.width; 
    canvas.height = imgObj.height; 
    //draw image on canvas, full canvas API is described here http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html 
    ctx.drawImage(imgObj, 0, 0); 
    //get array of image pixels 
    var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height); 
    //run through all the pixels 
    for(var y = 0; y < imgPixels.height; y++){ 
     for(var x = 0; x < imgPixels.width; x++){ 
      //here is x and y are multiplied by 4 because every pixel is four bytes: red, green, blue, alpha 
      var i = (y * 4) * imgPixels.width + x * 4; //Why is this multiplied by 4? 
      //compute average value for colors, this will convert it to bw 
      var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3; 
      //set values to array 
      imgPixels.data[i] = avg; 
      imgPixels.data[i + 1] = avg; 
      imgPixels.data[i + 2] = avg; 
     } 
    } 
    //draw pixels according to computed colors 
    ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height); 
    return canvas.toDataURL(); 
} 

在這個函數中係數等於1/3的使用,然而通常使用的是:0.3R + 0.59G + 0.11B(http://gimp-savvy.com/BOOK/index html的?node54.html)。

+1

+1提到做「灰度」的「正確」方式。 –

+1

即使是黑白/灰度圖像,圖像是否仍然保存爲全綵模式?如果我想要將純黑白畫布保存爲黑白圖像(小得多的文件大小),該怎麼辦? –