« あーだこーだ考えるよりライブコーディング | メイン | 弾幕時計 -BULLET CLOCK- »

ActionScript 3.0 でラベリング (改)を勝手に添削

超絶技巧発表会の資料を参照しておきながら、てっく煮ブログ:ActionScript 3.0 でラベリング (改)でラベリング時にピクセル全走査やってるのが気になってしょうがなかったので添削エントリ書かせてもらいます(笑)

いきなり改良版ソースコード

function labeling2(src:BitmapData):BitmapData {
var dst:BitmapData = src.clone(); // ソースの複製を作る
var lno:int = 0;
var rect:Rectangle = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );

while ( !rect.isEmpty() ){
for ( var x:int = rect.left; x< rect.right; x++) {
if ( dst.getPixel( x, rect.top ) == 0xffffff ){
dst.floodFill( x, rect.top, ++lno );
rect = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
}
}
}
return dst;
}


BitmapData.getColorBoundsRectメソッドは引数で指定した色が含まれる領域を返してくれるので、最初から検索範囲を絞ることができます。
また、ラベリングの floodFill によって自動的に領域がごっそり消えるので再度メソッドを呼べばさらに検索範囲を絞られる、この繰り返しでさらに高速化を図ることができます。

うちの環境では4~5倍改善されましたが、ラベリング対象が複雑に絡み合った形状をしていると逆に遅くなる可能性があるので、検証する余地はありそうです。


ちなみに横方向走査まで getColorBoundsRect でやってみたら若干重くなりました。
やりすぎイクナイ!

書き方が悪かっただけでした・・・これで一切getPixelなしでいける上に速くなります。

というわけで、さらに改良版ソースコード。

function labeling2(src:BitmapData):BitmapData {
var dst:BitmapData = src.clone(); // ソースの複製を作る
var temp:BitmapData = new BitmapData( dst.width, 1, false, 0x000000 );
var lno:int = 0;
var zero:Point = new Point();
var rect:Rectangle = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
var area:Rectangle = new Rectangle( 0, 0, dst.width, 1 );

while ( !rect.isEmpty() ){
area.y = rect.top;
temp.copyPixels( dst, area, zero );
rect = temp.getColorBoundsRect( 0xffffff, 0xffffff, true );
dst.floodFill( rect.x, area.y, ++lno );
rect = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
}

return dst;
}

トラックバック

このエントリーのトラックバックURL:
http://void.heteml.jp/mt/mt-tb.cgi/95

コメントを投稿

あわせて読みたい