背景:有一天接到一個小遊戲,裡面有一個部分是 一起來找茬,一開始準備用設計給的坐標來寫,但是發現好像不太符合程序員愛鑽研的精神,於是就想著做一個能自動識別的,幾經周折,後來決定用 canvas的像素來處理這個問題。
熟悉API
在處理圖片找茬前,先啰嗦一下,canvas像素處理裡面最重要的兩個API ctx.getImageData
和ctx.putImageData
,前者負責獲取canvas像素信息,後者負責把像素信息繪製到canvas畫布上。
處理像素前,首先得在畫布上 畫寫東西,我們這裡就以畫兩個圖片為例,如下:
1.繪製圖片
ctx1.drawImage(img1, 0, 0, img1.width, img1.height, 0, 0, cavsW, cavsH);
ctx2.drawImage(img2, 0, 0, img2.width, img2.height, 0, 0, cavsW, cavsH);
2.獲取像素的API ctx.getImageData
MDN上的解釋是:
CanvasRenderingContext2D.getImageData()
返回一個ImageData對象,用來描述canvas區域隱含的像素數據,這個區域通過矩形表示,起始點為(sx, sy)、寬為sw、高為sh。;
sx
: 將要被提取的圖像數據矩形區域的左上角 x 坐標。
sy
: 將要被提取的圖像數據矩形區域的左上角 y 坐標。
sw
: 將要被提取的圖像數據矩形區域的寬度。
sh
: 將要被提取的圖像數據矩形區域的高度。
返回值
一個ImageData
對象,包含canvas給定的矩形圖像數據。其中,
ImageData.data
: Uint8ClampedArray 描述了一個一維數組,包含以 RGBA 順序的數據,數據使用 0 至 255(包含)的整數表示。
ImageData.height
: 無符號長整型(unsigned long),使用像素描述 ImageData 的實際高度。
ImageData.width
: 無符號長整型(unsigned long),使用像素描述 ImageData 的實際寬度。
下面,以一個寬高分別為750
和400
的canvas畫布為例:
ctx.getImageData(x,y, caves.width, canvas.height);
// 獲取的是一個包含像素信息的對象,如下
ImageData = {
data: Uint8ClampedArray(1200000), // 4 * 750 * 400
width: 750,
height: 400
}
由於ImageData.data是一維數組,所以我們需要把canvas的像素平鋪到一行,如下圖: