In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

細線化と境界抽出

画像処理の練習 -->細線化と境界抽出
/**
 * Copyright termat ( http://wonderfl.net/user/termat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/itjD
 */

/*
	画像処理の練習 -->細線化と境界抽出
*/
package 
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;

	[SWF(framerate = "30", width = "480",height="480",backgroundColor="0xffffff")]
	public class Practice34 extends Sprite{
		private var text:TextField;
		private var image:StrImage;
		private var tf:TextFormat;
		
		public function Practice34() {
			text = new TextField();
			text.type = TextFieldType.INPUT;
			text.text = "2月28日";
			text.restrict = null;
			text.width = 60;	text.height = 20;
			text.border = true;
			text.x = 2;	text.y = 5;	
			addChild(text);
			var bt0:Button = new Button(30, 20, 4, "exe", 11);
			bt0.x = 50;	bt0.y = 5;
			bt0.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void { image.draw(text.text, tf);} );
			addChild(bt0);
			tf = new TextFormat();
			tf.size = 128;
			tf.color = 0x000000;
			tf.bold = true;
			image = new StrImage(text.text, tf);
			addChild(image);
			image.x = 5;	image.y = 30;
		}	
	}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.ColorMatrixFilter;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;

class StrImage extends MovieClip {
	public var bmpdata:BitmapData;
	public var thin:BitmapData;
	public var border:BitmapData;
	private var bmp:Bitmap;
	private var list:Vector.<uint>;
	
	public function StrImage(str:String,format:TextFormat):void {
		var text:TextField = new TextField();
		text.defaultTextFormat = format;
		text.text = str;
		text.width = text.textWidth;
		text.height = text.textHeight;
		bmpdata = new BitmapData(text.textWidth + 2, text.textHeight + 2, false, 0xffffff);
		bmpdata.fillRect(bmpdata.rect,0xffffff);
		bmpdata.lock();
		bmpdata.draw(text);
		bmpdata.unlock();
		addChild(new Bitmap(bmpdata, "auto", true));
		thin = new BitmapData(text.textWidth + 2, text.textHeight + 2, false, 0xffffff);
		thin.fillRect(thin.rect, 0xffffff);
		var b2:Bitmap = new Bitmap(thin, "auto", true);
		b2.y = bmpdata.height + 5;
		addChild(b2);
		border = new BitmapData(text.textWidth + 2, text.textHeight + 2, false, 0xffffff);
		border.fillRect(border.rect, 0xffffff);
		var b3:Bitmap = new Bitmap(border, "auto", true);
		b3.y = bmpdata.height * 2 + 10;
		addChild(b3);
	}
	
	public function draw(str:String,format:TextFormat):void {
		var text:TextField = new TextField();
		text.defaultTextFormat = format;
		text.text = str;
		text.width = text.textWidth;
		text.height = text.textHeight;
		bmpdata.fillRect(bmpdata.rect,0xffffff);
		bmpdata.lock();
		bmpdata.draw(text);
		bmpdata.unlock();
		traceBorder();
		thinning();
	}
	
	public function thinning():void {
		thin.fillRect(thin.rect,0xffffff);
		var main:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
		var sub:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
		for (var x:int = 0; x < bmpdata.width; x++) {
			var mp:Vector.<uint> = new Vector.<uint>();
			var ss:Vector.<uint> = new Vector.<uint>();
			for (var y:int = 0; y < bmpdata.height; y++) {
				if (bmpdata.getPixel(x, y) == 0x000000) {
					mp[y] = 1;	ss[y] = 1;
				}else {
					mp[y] = 0;	ss[y] = 0;
				}
			}
			main[x] = mp;	sub[x] = ss;
		}
		var aa:Array = [0, 0, 0, 0, 0, 0, 0, 0, 0];
		var bb:Array = [0, 0, 0, 0, 0, 0, 0, 0, 0];
		var rev:int = 1;
		var num:int = 0;
		while(rev!=0){
			rev=0;
			num++;
			for(y=1;y<bmpdata.height-1;y++){
				for(x=1;x<bmpdata.width-1;x++){
					if(main[x][y]==0)continue;
					aa[0]=main[x+1][y];		bb[0]=sub[x+1][y];
					aa[1]=main[x+1][y-1];	bb[1]=sub[x+1][y-1];
					aa[2]=main[x][y-1];		bb[2]=sub[x][y-1];
					aa[3]=main[x-1][y-1];	bb[3]=sub[x-1][y-1];
					aa[4]=main[x-1][y];		bb[4]=sub[x-1][y];
					aa[5]=main[x-1][y+1];	bb[5]=sub[x-1][y+1];
					aa[6]=main[x][y+1];		bb[6]=sub[x][y+1];
					aa[7]=main[x+1][y+1];	bb[7]=sub[x+1][y+1];
					var sum:int=0;
					for (var i:int=0;i<8;i++) sum +=aa[i];
					if(sum==0)sub[x][y]=0;
					if(sum>=2&&sum<=5){
						if(connect(aa)==1&&connect(bb)==1){
							for(var j:int=1;j<5;j++){
								if(bb[j]==0){
									var c:int=aa[j];
									aa[j]=0;
									if(connect(aa)!=1){
										aa[j]=c;
										break;
									}
									aa[j]=c;
								}
								sub[x][y]=0;
							}
						}
					}
					if(sub[x][y]==0)rev++;
				}
			}
			for(y=1;y<bmpdata.height-1;y++){
				for(x=1;x<bmpdata.width-1;x++){
					main[x][y]=sub[x][y];
				}
			}
		}
		for (y = 1; y < bmpdata.height - 1; y++) {
			for (x = 1; x < bmpdata.width-1; x++) {
				if (main[x][y] == 1) thin.setPixel(x, y, 0xff0000);
			}
		}
	}
	
	private function connect(val:Array):int {
		val[8]=val[0];
		var num:int=0;
		for (var i:int = 1; i < val.length; i++) {
			if (val[i] == 1 && val[i - 1] == 0) num++;
		}
		return num;
	}
	
	public function traceBorder():void {
		border.fillRect(thin.rect,0xffffff);
		var p:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
		var b:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
		for (var x:int = 0; x < bmpdata.width; x++) {
			var mp:Vector.<uint> = new Vector.<uint>();
			var ss:Vector.<uint> = new Vector.<uint>();
			for (var y:int = 0; y < bmpdata.height; y++) {
				if (bmpdata.getPixel(x, y) == 0x000000) {
					mp[y] = 1;
					ss[y] = 0;
				}else {
					mp[y] = 0;
					ss[y] = 0;
				}
			}
			p[x] = mp;
			b[x] = ss;
		}
		b=border_trace(p,b);
		for(y=0;y<bmpdata.height;y++){
			for(x=0;x<bmpdata.width;x++){
				if (b[x][y] == 1) border.setPixel(x, y, 0xff0000);
			}
		}
	}
	
	private function border_trace(p:Vector.<Vector.<uint>>,b:Vector.<Vector.<uint>>):Vector.<Vector.<uint>>{
		var code:int=0;
		for(var y:int=1;y<bmpdata.height-1;y++){
			for(var x:int=1;x<bmpdata.width-1;x++){
 				if(p[x][y]==1&&b[x][y]==0){
					if(p[x-1][y]==0){
						code=0;
						trace(x,y,code,p,b);
					}else if(p[x+1][y]==0){
						code=4;
						trace(x,y,code,p,b);
					}
				}
			}
		}
		return b;
	}
	
	private function trace(x:int,y:int,code:int,p:Vector.<Vector.<uint>>,b:Vector.<Vector.<uint>>):void{
		if(!check(x,y,p))return;
		var xs:int= x;	var ys:int=y;	var x1:int=x;	var x2:int=0;	var y1:int=y;	var y2:int=0;
		while(x2!=xs||y2!=ys){
			switch(code){
				case 0:
					x2=x1;
					y2=y1+1;
					if(y2<height&&p[x2][y2]==1){
						code=6;
					}else{
						code=2;
					}
					break;
				case 2:
					x2=x1+1;
					y2=y1;
					if(x2<width&&p[x2][y2]==1){
						code=0;
					}else{
						code=4;
					}
					break;
				case 4:
					x2=x1;
					y2=y1-1;
					if(y2>=0&&p[x2][y2]==1){
						code=2;
					}else{
						code=6;
					}
					break;
				case 6:
					x2=x1-1;
					y2=y1;
					if(x2>=0&&p[x2][y2]==1){
						code=4;
					}else{
						code=0;
					}
					break;
			}
			if(x2>=0&&x2<width&&y2>=0&&y2<height){
				if(p[x2][y2]==1){
					b[x2][y2]=1;
					x1=x2;
					y1=y2;
				}
			}
		}
	}
	
	private function check(x:int,y:int,p:Vector.<Vector.<uint>>):Boolean{
		if(p[x-1][y]==0&&p[x+1][y]==0&&p[x][y-1]==0&&p[x][y+1]==0){
			return false;
		}else{
			return true;
		}
	}
	
}

class Button extends Sprite{
	private static const mono:ColorMatrixFilter = new ColorMatrixFilter([
		1 / 3, 1 / 3, 1 / 3, 0, 10, 1 / 3, 1 / 3, 1 / 3, 0, 10,
		1 / 3, 1 / 3, 1 / 3, 0, 10, 0,0,0, 1, 0]);
	private var _hover:Boolean = false;
	public function get hover():Boolean{
		return _hover;
	}
	public function set hover(value:Boolean):void{
		if(_hover != value){
			_hover = value;
			filters = (_hover ? null : [mono]);
		}
	}

	public function Button(W:Number, H:Number, R:Number, label:String = "", size:int = 11){
		var matrix:Matrix = new Matrix();
		matrix.createGradientBox(W, H, Math.PI / 2);
        var bg:Sprite = new Sprite();
		bg.graphics.beginGradientFill("linear", [0xDDE9F4, 0xD5E4F1, 0xBAD2E8], [1, 1, 1],[0, 120, 136], matrix);
		bg.graphics.drawRoundRect(0, 0, W, H, R, R);
		bg.graphics.endFill();
		bg.filters = [new GlowFilter(0xFFFFBE, .5, 10, 10, 2, 1, true)];
		addChild(bg);
		var line:Sprite = new Sprite();
		line.graphics.lineStyle(3, 0xBAD2E8);
		line.graphics.drawRoundRect(0, 0, W, H, R, R);
		addChild(line);
        filters = [mono];
        buttonMode = true;
        mouseChildren = false;
        if (label != ""){
			var textField:TextField = new TextField();
			textField.selectable = false;
			textField.autoSize = "left";
			textField.htmlText = <font size={size} color="#6B8399">{label}</font>.toXMLString();
			textField.x = (W - textField.width) / 2;
			textField.y = (H - textField.height) / 2;
			addChild(textField);
		}
		addEventListener("rollOver", buttonRollOver);
		addEventListener("rollOut", buttonRollOut);
		addEventListener("removed", function(event:Event):void{
			removeEventListener("rollOver", buttonRollOver);
			removeEventListener("rollOut", buttonRollOut);
			removeEventListener("removed", arguments.callee);
		});
	}

	protected function buttonRollOver(event:Event):void{
		hover = true;
	}

	protected function buttonRollOut(event:Event):void{
		hover = false;
	}
}