forked from: forked from: ゆっくり塗りつぶす

by taka_milk
画像クリックでゆっくりと塗りつぶしていく
* [file upload]ボタンクリックでファイル選択ダイアログから画像を指定する版
* 
♥0 | Line 185 | Modified 2009-11-16 09:25:28 | MIT License
play

ActionScript3 source code

/**
 * Copyright taka_milk ( http://wonderfl.net/user/taka_milk )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sutm
 */

// forked from ep91ckok's forked from: ゆっくり塗りつぶす
// forked from ep91ckok's ゆっくり塗りつぶす
/*
 * 画像クリックでゆっくりと塗りつぶしていく
 * [file upload]ボタンクリックでファイル選択ダイアログから画像を指定する版
 * */
package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	
	[SWF(frameRate = "60", backgroundColor = "#ffffff")]
	public class Main extends Sprite 
	{
		private var _button:TextField;
		private var _canvas:Sprite;
		private var _bmp:Bitmap;
		private var _bmpData:BitmapData;
		private var _origBmpData:BitmapData;
		private var _color:Array;
		private var _list:Array;
		private var _listNext:Array;
		private var _W:int;
		private var _H:int;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			var isd:ImageSelectDialog = new ImageSelectDialog();
			isd.onComplete = function():void {
				_origBmpData = isd.bitmapData.clone();
				init2();
			};
			isd.button.addEventListener(MouseEvent.MOUSE_UP, function():void {
				stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
				stage.removeEventListener(Event.ENTER_FRAME, frame);
			});
			addChild(isd.button);
			
			_canvas = new Sprite();
			_canvas.y = isd.button.height + 5;
			addChild(_canvas);
		}
		
		private function init2():void
		{
			_bmpData = _origBmpData.clone();
			
			_bmp =  new Bitmap(_bmpData);
			if (_canvas.numChildren)	_canvas.removeChildAt(0);
			_canvas.addChild(_bmp);
			
			_W = _bmpData.width
			_H = _bmpData.height;
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			var px:int = _bmp.mouseX;
			var py:int = _bmp.mouseY;
			if (px < 0) return;
			if (py < 0) return;
			if (px >= _W) return;
			if (py >= _H) return;
			
			_canvas.removeChild(_bmp);
			_bmpData = _origBmpData.clone();
			_bmp = new Bitmap(_bmpData);
			_canvas.addChild(_bmp);
			
			_list = [];
			_list.push(_bmp.mouseY * _W + _bmp.mouseX);
			
			_color = [];
			var color:Array = _color;
			var bmpData:BitmapData = _bmpData;
			var W:int = _W;
			var H:int = _H;
			for (var y:int = 0; y < H; y++)
				for (var x:int = 0; x < W; x++)
					color[y * W + x] = bmpData.getPixel(x, y);
			
			stage.addEventListener(Event.ENTER_FRAME, frame);
		}
		
		private function frame(e:Event):void
		{
			var bmpData:BitmapData = _bmpData;
			var color:Array = _color;
			var W:int = _W;
			var H:int = _H;
			var list:Array = _list;
			
			_listNext = [];
			var listNext:Array = _listNext;
			bmpData.lock();
			for each(var address:int in list)
			{
				var c:int = color[address];
				
				if (c < 0) continue; //既にカウント済ならば次のループへ
				
				var x:int = address % W;
				var y:int = address / W;
				
				// 隣のマスが同じ色だったら、そこを次にチェックするリストに加える
				if (0 <= x - 1 && c == color[address - 1])	// y*W+(x-1) == y*W+x-1 == address-1
					listNext.push(address - 1);
				if (x + 1 < W && c == color[address + 1])	// y*W+(x+1) == y*W+x+1 == address+1
					listNext.push(address + 1);
				if (0 <= y - 1 && c == color[address - W])	// (y-1)*W+x == y*W+x-W == address-W
					listNext.push(address - W);
				if (y + 1 < H && c == color[address + W])	// (y+1)*W+x == y*W+x+W == address+W
					listNext.push(address + W);
				
				color[address] = -1;
				
				bmpData.setPixel(x, y, 0xff0000);
			}
			bmpData.unlock();
			
			if (_listNext.length == 0)
			{
				stage.removeEventListener(Event.ENTER_FRAME, frame);
				return;
			}
			
			_list = _listNext;
		}
	}
}

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.FileReference;
import flash.display.BitmapData;
import flash.net.FileFilter;
import flash.utils.ByteArray;
import flash.display.Loader;
import flash.text.TextField;
import flash.events.MouseEvent;

class ImageSelectDialog extends EventDispatcher
{
	private var _fileRef:FileReference = new FileReference();
	private var _button:TextField;
	private var _bitmapData:BitmapData;
	private var _onComplete:Function = function():void { };
	
	public function get button():TextField
	{
		return _button;
	}
	
	public function get bitmapData():BitmapData
	{
		return _bitmapData;
	}
	
	public function set onComplete(func:Function):void
	{
		_onComplete = func;
	}
	
	public function get complete():String
	{
		return "complete";
	}
	
	//////
	
	public function ImageSelectDialog():void
	{
		_button = new TextField();
		_button.autoSize = "left";
		_button.border = true;
		_button.text = "file upload";
		_button.selectable = false;
		_button.addEventListener(MouseEvent.MOUSE_UP, function():void {
			addEventListener(complete, function():void {
			    removeEventListener(complete, arguments.callee);
				_onComplete();
			});
			openDialog();
		});
	}
	
	public function openDialog():void
	{
		_fileRef.addEventListener(Event.SELECT, onFileSelect);
		_fileRef.browse([new FileFilter("images", "*.jpg;*.png;*.gif")]);
	}
	
	private function onFileSelect(e:Event):void
	{
		_fileRef.removeEventListener(Event.SELECT, onFileSelect);
		_fileRef.addEventListener(Event.COMPLETE, onFileComplete);
		_fileRef.load();
	}
	
	private function onFileComplete(e:Event):void
	{
		_fileRef.removeEventListener(Event.COMPLETE, onFileComplete);
		
		var byteArr:ByteArray = _fileRef.data;
		
		var loader:Loader = new Loader();
		loader.loadBytes(byteArr);
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void{
			_bitmapData = new BitmapData(loader.width, loader.height);
			_bitmapData.draw(loader);
			
			dispatchEvent(new Event(complete));
		});
	}
}