BitmapDataの範囲拡張&収縮
てっく煮ブログ:BitmapDataの範囲拡張をするなら・・・では全ピクセルをチェックしていますが、それよりも圧倒的に軽く処理できる方法があるので紹介しておきます。
マウスで適当に線を描いて、上下キーで拡張・収縮できます。
別段難しいことをしているわけではなく、コンボリューションフィルタ使った結果をdrawしてるだけなのですが、ちょっと手抜きしたので拡張があまり綺麗じゃない・・・
もう少し作り込めば収縮と同じような感じで拡張を行えるはずですが、いずれにせよこの手の処理はビットマップのメソッドだけでやれることが多いのでアルゴリズムを考えてみると楽しいと思います。
(ブラーフィルタかけてからスレッショルドで削ることでマシになりました。ソースも微修正)
ソースは以下。
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.filters.ConvolutionFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.ui.Keyboard;
import flash.geom.ColorTransform;
[SWF(backgroundColor=0xffffff, frameRate='60', width='320', height='240')]
public class DilateAndErode extends Sprite {
private var bd:BitmapData;
private var temp:BitmapData;
private var line:Sprite;
private var rect:Rectangle;
private var zero:Point;
private var mtx:Matrix;
private var dilate_bf:BlurFilter;
private var erode_cf:ConvolutionFilter;
public function DilateAndErode() {
bd = new BitmapData( stage.stageWidth, stage.stageHeight, false, 0xffffff );
temp = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0x00ffffff );
addChild( new Bitmap( bd ) );
line = addChild( new Sprite() ) as Sprite;
var frame:Shape = addChild( new Shape() ) as Shape;
frame.graphics.lineStyle( 2, 0 );
frame.graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
rect = bd.rect;
zero = rect.topLeft;
mtx = new Matrix();
dilate_bf = new BlurFilter( 4, 4, 3 );
erode_cf = new ConvolutionFilter( 3, 3, [ 0, 1, 0, 1, 1, 1, 0, 1, 0 ], 5, 0, true );
stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );
}
private function mouseDownHandler( e:MouseEvent ):void {
var g:Graphics = line.graphics;
g.lineStyle( 5, 0x000000, 1 );
g.moveTo( stage.mouseX, stage.mouseY );
var mouseMoveFunc:Function = function( e:MouseEvent ):void {
g.lineTo( stage.mouseX, stage.mouseY );
}
var mouseUpFunc:Function = function( e:MouseEvent ):void {
stage.removeEventListener( MouseEvent.MOUSE_MOVE, mouseUpFunc );
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseUpFunc );
bd.draw( line );
g.clear();
}
stage.addEventListener( MouseEvent.MOUSE_MOVE, mouseMoveFunc );
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpFunc );
}
private function keyDownHandler( e:KeyboardEvent ):void {
switch ( e.keyCode ) {
case Keyboard.UP:
temp.applyFilter( bd, rect, zero, dilate_bf );
temp.threshold( temp, rect, zero, ">", 0x000000c0, 0xffffffff, 0x000000ff );
bd.draw( temp, mtx, null, "multiply");
break;
case Keyboard.DOWN:
temp.applyFilter( bd, rect, zero, erode_cf );
bd.draw( temp, mtx, null, "add");
break;
}
}
}
}
