2024年5月19日 星期日

JavaScript : 偵測圖片的範圍

2024年5月19日 星期日

 前幾天看到一篇「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)) {
  ......
  ......
}

它是陣列中的元素只要任何一個符合條件,就回傳 true,用來檢查一個點的四筆資料是否有畫上東西(大於 0 ),滿合用的。

我將作者用 filter 取圖點資料的部份去掉,來做一下效率上的比較。在底下的 canvas 上按一下,程式會載入 HTML5 FUN 的小圖示,並畫在亂數取的位置,然後再找出它的邊界。依序使用原作者的演算法,跟改直接由 while 迴圈內取圖形資料,及改直接由 for 迴圈內取圖形資料,看看這三種方法,各使用了多少毫秒。

按這裡開始測試



沒有留言:

張貼留言

 
雄::gsyan © 2009. Design by Pocket