前幾天看到一篇「Detecting content boundaries on a HTML5 canvas」:
作者介紹如何在 canvas 中找出有畫圖部份的矩形範圍,基本原理就是取出 canvas 的所有點的資料,然後由上往下,一次取一橫排,一個點、一個點的檢查是否有著色,直到最行一橫排檢查完為止。這部份以前有寫過類似的程式碼,此篇中,多學了幾個有關 JavaScript 陣列的操作:
- Array.from()
- Array.prototype.filter()
- Array.prototype.some()
當我們使用 canvas Context 的 getImageData 取得圖形的資料時,預設每一個點會使用到四筆資料,作者是先使用 filter() ,各點每四筆資料為一個元素,變成新的陣列 pixels。
imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
let counter = 0;
const pixels = Array.from(imgData.data).filter(() => {
if (counter === 3) {
counter = 0;
return true;
}
counter++;
return false;
});
在猜想,可能是為了簡化後面的程序才這樣操作,不過,這樣一來,照說會浪費掉一些運算的時間(稍候再來證明)。
使用「some()」倒是以前沒有注意到的方法,
const row = pixels.slice(y, y + canvas.width);
if (row.some(pixel => pixel > 0)) {
......
......
}
我將作者用 filter 取圖點資料的部份去掉,來做一下效率上的比較。在底下的 canvas 上按一下,程式會載入 HTML5 FUN 的小圖示,並畫在亂數取的位置,然後再找出它的邊界。依序使用原作者的演算法,跟改直接由 while 迴圈內取圖形資料,及改直接由 for 迴圈內取圖形資料,看看這三種方法,各使用了多少毫秒。
沒有留言:
張貼留言