js計算圖片內點個數

sXin發表於2019-04-01

前言

圖片是由連續的點資訊組成,每個點資訊包含四個長度即rgba資訊,通過遍歷配合處理函式實現對點個數的判斷。

js計算圖片內點個數

實現思路

本例子採用png格式圖片,只需要判該點透明度(opacity)是否為0即可確定是否為小球上一點,如果不為0,判斷上下左右方向的點是否透明度為0,不為0遞迴該結果,並且將該點的rgba資訊置為0;結束後開始下一個主迴圈並計數,直至迴圈結束。

具體步驟

  1. 建立canvas物件,載入目標圖片,使用canvas的drawImage方法將該圖片物件寫入canvas中;引數為圖片物件,貼圖起點橫座標,貼圖起點縱座標,貼圖寬度,貼圖高度。
    var canvas = document.createElement('canvas'),
    var ctx = canvas.getContext('2d');
    ctx.drawImage(imgObj, 0, 0,imgWidth,imgHeight);
複製程式碼
  1. 獲取圖片的相關資訊canvas的getImageData方法,需要使用圖片上各點的rgba資訊;引數為採點起始橫座標,採點起始縱座標,採點寬度,採點高度。
    var imageData = ctx.getImageData(0,0,width,height);
    //改寫imageData.data資訊實現點的計數
複製程式碼
  1. 遍歷圖片的點資訊imageData.data,四個點為一組增長條件為i+4,當透明度不為0時呼叫處理函式,並且終止迴圈(終止迴圈,防止短時間內迴圈次數過多造成記憶體溢位),迴圈條件為numberStart<imageData.data.length-1 結束,number為最終的點數量;numberStart為上次迴圈結束時點的索引值,number為點的數量,judgeZero為處理函式。
    function repeateData(){
        for(var i=numberStart;i<imageData.data.length;i+=4){
            numberStart+=4;
            var a = imageData.data[i+3];
            if(a != 0) {
                judgeZero(i,number);
                break;
            }
        }
        if(numberStart<imageData.data.length-1){
            repeateData()
        }else{
            console.log(number);
        }
    }
複製程式碼
  1. 點的處理函式,根據圖片的寬和高計算出點的座標(x,y),並且計算出該點上下左右四個點的透明度資訊。
    function judgeZero(index){
        number++;
        clearPoints(index);
    }
    function clearPoints(index){
        var x = (index/4)%width,
            y = Math.floor(index/4/width);

        var up = (x+(y-1)*width)*4,
            down = (x+(y+1)*width)*4,
            right = (x+1+y*width)*4,
            left = (x-1+y*width)*4;

        var uA = imageData.data[up+3],
            bA = imageData.data[down+3],
            rA = imageData.data[right+3],
            lA = imageData.data[left+3];
    }
    function clearRgb(index){
        imageData.data[index] = 0;
        imageData.data[index+1] = 0;
        imageData.data[index+2] = 0;
        imageData.data[index+3] = 0;
    }
複製程式碼
  1. 判斷四個方向的透明度是否為0,如果為0繼續呼叫,並且擦出該點資訊。
    if(uA != 0){
        clearRgb(up);
        clearPoints(up);
    }
    if(bA != 0){
        clearRgb(down);
        clearPoints(down);
    }
    if(rA != 0){
        clearRgb(right);
        clearPoints(right);
    }
    if(lA != 0){
        clearRgb(left);
        clearPoints(left);
    }
複製程式碼
  1. 將透明度不為0的所有點資訊置為0,之後該點不會對主迴圈的判斷有影響。
    function clearRgb(index){
        imageData.data[index] = 0;
        imageData.data[index+1] = 0;
        imageData.data[index+2] = 0;
        imageData.data[index+3] = 0;
    }
複製程式碼
  1. 執行4,5,6步驟直至所有點rgba資訊都被置為0,主迴圈繼續,最後可得到數量。

總結

主要的原理為獲取球上的一點,通過上下左右遞迴來判斷連續點並消除點資訊,至該點的資訊已在imageData.data中全部抹去,此過程記為1個點,主迴圈繼續;圖片為png格式,點的型別不限於圓形;該方法僅供參考。

相關文章