1

データが含まれている画像の最初の垂直および水平行を見つけようとしています。

を呼び出すgetImageDataと、結果のピクセルデータの配列が行ごとに水平に格納されるため、最初の水平行を簡単に取得できました。私はこのようなデータを持っています:

var data = context.getImageData(0, 0, width, height).data;
var heightFirst = 0;

for (var r = 0; r <= data.length; r += 4) {
    if (data[r + 3] > 0) {
        var y = (r / width) / 4;
        heightFirst = y;
        break;
    }
}

ここで、データを垂直方向に繰り返す必要があります。これはおそらく、ネストされた for ループを使用して、次のようなことを行っていることに気づきました。

for (var r = 0; r <= data.length; r += 4) {
    for (var c = 0; c < canvasHeight; c++) {    
        if (data[(r + 3) + (c * width)] > 0) {

        }
    }
}

正確な実装/計算がわからないのですが、誰か助けてもらえますか??

編集

@bobbybee と @danielpolencic が述べたように、幅が 4 ずつ増加するループは垂直列を増加させます。

for (var r = 0; r <= data.length; r += (4 * width)) {
  if (data[r + 3] > 0) {
    // do whatever
  }
}

ただし、これはピクセルの最初の列の情報のみを取得します。次のステップは、上記のループを繰り返すことですが、次のようなループで列の数 (カラー データのために 4 を掛けた値) をインクリメントします。

for (var c = 0; c < canvas.width; c ++) {
    for (var r = 0; r <= data.length; r += ((4 * canvas.width) + (c * 4))) {
        if (data[r + 3] > 0) {
            firstX = c;
        }
    }
}

これはあまり正しくないようです。ご覧のとおり、これは左から最初の列であるため、10 を返す必要がありますが、ログには 99 が書き込まれています。私がとても近くにいるように感じます!

4

3 に答える 3

2

入れ子にすることなく、単一のループですべてを実行できます。

ライブデモ

var minX = canvas.width,
    minY = canvas.height;

for (var p = 0; p <= data.length; p += 4) {
     var curX = (p / 4) % canvas.width,
         curY = ((p / 4) - curX) / canvas.width;

    /* if what we're checking is higher than our recorded minX and 
      minY skip to the next row */

    if(curX > minX && curY > minY){
        // if minY is greater than 0 continue, if its 0 it can be no less so break.
        if(minY > 0){
            p=(curY+1)*(canvas.width*4); 
        }else{
            break;
        }
    }

    if (data[p + 3] > 0) {
        if (curX < minX) {
            minX = curX;
        };

        if (curY < minY) {
            minY = curY;
        };
    }
}

以下は、1 次元配列から x と y を取得するための式です。

X = Index % Width

Y = (Index - x) / Width

この例では、4 つのコンポーネント値 (r/g/b/alpha) に分割されたピクセル データを使用しているため、上記のデモで行ったように、インデックスを 4 で割る必要があります。

次に、キャンバスの幅と高さを使用minXして設定します。minYピクセルにヒットするたびに、そのxまたはyが最低値よりも低くxy保存されているかどうかを確認します。それらが低い場合は、値を保持して先に進みます。

ただし、複数のループを使用してデータを読み取る方が読みやすく、高速です。

for (var x = 0; x <= canvas.width; x++) {
  for (var y = 0; y <= canvas.height; y++) {
    if (minY < y) {
      break;
    }
    if (data[((y * canvas.width + x) * 4) + 3] > 0) {
      if (x < minX) {
        minX = x;
      }
      if (y < minY) {
        minY = y;
      }
    }
  }
}

lastX と lastY を取得するデモ

for (var x = 0; x <= canvas.width; x++) {
    for (var y = 0; y <= canvas.height; y++) {
        if (data[((y * canvas.width + x) * 4) + 3] > 0) {
            if (x < firstX) {
                firstX = x;
            }
            if (y < firstY) {
                firstY = y;
            }

            if (x > lastX) {
                lastX = x;
            }
            if (y > lastY) {
                lastY = y;
            }
        }
    }
}
于 2013-08-14T02:21:39.907 に答える