前言
圖片是由連續的點資訊組成,每個點資訊包含四個長度即rgba資訊,通過遍歷配合處理函式實現對點個數的判斷。
實現思路
本例子採用png格式圖片,只需要判該點透明度(opacity)是否為0即可確定是否為小球上一點,如果不為0,判斷上下左右方向的點是否透明度為0,不為0遞迴該結果,並且將該點的rgba資訊置為0;結束後開始下一個主迴圈並計數,直至迴圈結束。
具體步驟
- 建立canvas物件,載入目標圖片,使用canvas的drawImage方法將該圖片物件寫入canvas中;引數為圖片物件,貼圖起點橫座標,貼圖起點縱座標,貼圖寬度,貼圖高度。
var canvas = document.createElement('canvas'),
var ctx = canvas.getContext('2d');
ctx.drawImage(imgObj, 0, 0,imgWidth,imgHeight);
複製程式碼
- 獲取圖片的相關資訊canvas的getImageData方法,需要使用圖片上各點的rgba資訊;引數為採點起始橫座標,採點起始縱座標,採點寬度,採點高度。
var imageData = ctx.getImageData(0,0,width,height);
//改寫imageData.data資訊實現點的計數
複製程式碼
- 遍歷圖片的點資訊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);
}
}
複製程式碼
- 點的處理函式,根據圖片的寬和高計算出點的座標(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;
}
複製程式碼
- 判斷四個方向的透明度是否為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);
}
複製程式碼
- 將透明度不為0的所有點資訊置為0,之後該點不會對主迴圈的判斷有影響。
function clearRgb(index){
imageData.data[index] = 0;
imageData.data[index+1] = 0;
imageData.data[index+2] = 0;
imageData.data[index+3] = 0;
}
複製程式碼
- 執行4,5,6步驟直至所有點rgba資訊都被置為0,主迴圈繼續,最後可得到數量。
總結
主要的原理為獲取球上的一點,通過上下左右遞迴來判斷連續點並消除點資訊,至該點的資訊已在imageData.data中全部抹去,此過程記為1個點,主迴圈繼續;圖片為png格式,點的型別不限於圓形;該方法僅供參考。