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

色要素の分解

赤いボタンで新規読み込み
青いボタンで登録されてあるプリセットを表示

アイコンの色を分解するコード。
ゲームなどで、アイコンの色によってパラメータを決める場合などに使う。
左から使用優先度が高い。
減色アルゴリズムというわけではない。

アイコン読み込みにhttp://blog.livedoor.jp/dankogai/archives/51331768.html
を使ったのだけど、クロスドメイン周りが上手く表示できなくて、力技になってしまった。
Get Adobe Flash player
by tail_y 30 Dec 2010
/**
 * Copyright tail_y ( http://wonderfl.net/user/tail_y )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/k1Ty
 */

package{
	import flash.system.Security;
	import flash.system.LoaderContext;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.ui.Keyboard;

	/**
	 * @author tail
	 */
	public class ColorSplit extends Sprite{
		private var _template:WonderflTemplate;
		
		private static const _testList:String = "tail_y,chibitami,clockmaker,fumix,paq89,alumican_net,beinteractive,orangesuzuki,doke,whirlpower";
		private static const _size:int = 48;
		
		private var _lastListI:int = -1;
		
		private var _inputTf:TextField;
		private var _inputBtn:Sprite;
		private var _presetBtn:Sprite;
		private var _loader:Loader;
		private var _bmd:BitmapData;
		
		private var _paletIndex:Object;
		private var _palet:Vector.<PaletData> = new Vector.<PaletData>();
		
		private var _displayBarBmp:BitmapData = new BitmapData(1, 1);
		private var _displayBar:Bitmap = new Bitmap();
		private var _displayBitmap:Bitmap = new Bitmap();
		
		private static const _shortRate:int = 6;
		private static const _whiteLine:int = 0xf3;
		
		public function ColorSplit(){
			_template = new WonderflTemplate();
			_template.Initialize(this, Initialize, 20, 0x888888, 5);
		}
		public function Initialize():void{
			
			_inputTf = new TextField();
			_inputTf.height = 20;
			_inputTf.width = 300;
			_inputTf.background = true;
			_inputTf.type = TextFieldType.INPUT;
			addChild(_inputTf);
			
			_inputBtn = new Sprite();
			_inputBtn.graphics.beginFill(0xff8888, 1);
			_inputBtn.graphics.drawRect(300, 0, 50, 20);
			_inputBtn.addEventListener(MouseEvent.CLICK, input);
			_inputBtn.buttonMode = true;
			addChild(_inputBtn);
			
			_presetBtn = new Sprite();
			_presetBtn.graphics.beginFill(0x8888ff, 1);
			_presetBtn.graphics.drawRect(360, 0, 50, 20);
			_presetBtn.addEventListener(MouseEvent.CLICK, setRandom);
			_presetBtn.buttonMode = true;
			addChild(_presetBtn);
			
			_displayBitmap = new Bitmap();
			_displayBitmap.y = 30;
			addChild(_displayBitmap);
			
			_displayBar = new Bitmap(_displayBarBmp);
			_displayBar.y = 30 + 60;
			_displayBar.height = 20;
			_displayBar.width = 10;
			addChild(_displayBar);
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, key);
			setRandom(null);
		}
		private function setRandom(event:MouseEvent):void{
			var testList:Array = _testList.split(",");
			if (_lastListI == -1){
				_lastListI = int(Math.random() * testList.length);
			}else{
				_lastListI++;
				_lastListI %= testList.length;
			}
			_inputTf.text = testList[_lastListI];
			input(null);
		}
		private function key(event:KeyboardEvent):void{
			if (event.keyCode == Keyboard.ENTER){
				input(null);
			}
		}
		private function input(event:MouseEvent):void{
			Security.loadPolicyFile("http://a0.twimg.com/crossdomain.xml");
			Security.loadPolicyFile("http://a1.twimg.com/crossdomain.xml");
			Security.loadPolicyFile("http://a2.twimg.com/crossdomain.xml");
			Security.loadPolicyFile("http://a3.twimg.com/crossdomain.xml");
			Security.loadPolicyFile("http://a4.twimg.com/crossdomain.xml");
			Security.loadPolicyFile("http://a5.twimg.com/crossdomain.xml");
			_loader = new Loader();
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
			_loader.load(new URLRequest("http://api.dan.co.jp/twicon/" + _inputTf.text + "/normal"));
		}
		private function loadComplete(event:Event):void{
			trace("loadComplete");
			var tmpBmd:BitmapData = Bitmap(_loader.content).bitmapData;
			var scale:Number = _size / Math.max(tmpBmd.width, tmpBmd.height);
			_bmd = new BitmapData(_size, _size, false, 0xffffff);
			_bmd.draw(tmpBmd, new Matrix(scale, 0, 0, scale));
			_displayBitmap.bitmapData = _bmd;
			start();
		}
		private function start():void{
			// 色情報を抽出し、パレットに割り当てる。
			_palet = new Vector.<PaletData>();
			_paletIndex = {};
			// 2隅が白なら、白を除外する
			var whiteCount:int = 0;
			if (isWhite(0, 0)) whiteCount++;
			if (isWhite(0, _size-1)) whiteCount++;
			if (isWhite(_size-1, 0)) whiteCount++;
			if (isWhite(_size-1, _size-1)) whiteCount++;
			var whiteIgunore:Boolean = (2 <= whiteCount);
			trace("whiteIgunore", whiteIgunore);
			// 走査
			var paletI:int = 0;
			var paletData:PaletData;
			var color:uint;
			var r:int, g:int, b:int;
			var min:int, max:int, s:int;
			var shortColor:int;
			for (var pointX:int = 0; pointX < _size; pointX++) {
				for (var pointY:int = 0; pointY < _size; pointY++) {
					color = _bmd.getPixel(pointX, pointY);
					r = (color >> 16)	& 0xFF;
					g = (color >> 8)	& 0xFF;
					b = (color)			& 0xFF;
					shortColor = (r >> _shortRate) * 0x100 + (g >> _shortRate) * 0x10 + (b >> _shortRate);
					min = Math.min(r, g, b);
					max = Math.max(r, g, b);
					s = (max == 0) ? 0 : (max - min) / max;
					if (whiteIgunore && _whiteLine < min) continue;
					var label:String = "p" + shortColor;
					if (_paletIndex[label] == null){
						paletData = new PaletData();
						_palet.push(paletData);
						_paletIndex[label] = paletI++;
						paletData.color = color;
						paletData.lastS = s;
						paletData.num = 0;
					}else{
						paletData = _palet[_paletIndex[label]];
						if (paletData.lastS < s){
							paletData.color = color;
							paletData.lastS = s;
						}
						paletData.num++;
					}
				}
			}
			// パレット数がいくつになったか
			trace("paletNum", paletI);
			// パレットのデバッグ表示
			_displayBarBmp.dispose();
			_displayBarBmp = new BitmapData(_palet.length, 1);
			_displayBar.bitmapData = _displayBarBmp;
			//
			_palet.sort(sortFunction);
			var displayBarX:int = 0;
			for each (paletData in _palet) {
				_displayBarBmp.setPixel(displayBarX++, 0, paletData.color);
			}
		}
		private function isWhite(x:int, y:int):Boolean{
			var color:uint = _bmd.getPixel(x, y);
			var min:int = Math.min((color >> 16) & 0xFF, (color >> 8) & 0xFF, (color) & 0xFF);
			return _whiteLine < min;
		}
		private function sortFunction(x:PaletData, y:PaletData):Number{
			if (x.num < y.num){
				return 1;
			}
			return -1;
		}
	}
}
class PaletData{
	public var color:uint;
	public var lastS:int;
	public var num:int;
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
/* 初期化テンプレート*/
class WonderflTemplate{
	public const WIDTH:int = 465;
	public const HEIGHT:int = 465;
	
	private var _target:Sprite;
	private var _handler:Function;
	
	private var _assetList:Object = {};
	private var _completeNum:int = 0;
	private var _totalNum:int = 0;
	
	public function addImageAsset(url:String, id:String = ""):void{
		addAsset(url, id, AssetData.TYPE_IMAGE);
	}
	public function addSwfAsset(url:String, id:String = ""):void{
		addAsset(url, id, AssetData.TYPE_SWF);
	}
	public function addTextAsset(url:String, id:String = ""):void{
		addAsset(url, id, AssetData.TYPE_TEXT);
	}
	private function addAsset(url:String, id:String, type:String):void{
		if (id == "") id = url;
		_totalNum++;
		_assetList[id] = new AssetData(url, id, type, loadComplete, loadError);
	}
	
	public function Initialize(target:Sprite, handler:Function, fps:Number, bgColor:uint, captureDelay:int):void{
		_target = target;
		_handler = handler;

		target.stage.frameRate = fps;
		target.stage.scaleMode = StageScaleMode.NO_SCALE;
		target.stage.align = StageAlign.TOP_LEFT;
		
		var bg:Bitmap = new Bitmap(new BitmapData(WIDTH, HEIGHT, false, bgColor));
		target.addChild(bg);
		Wonderfl.capture_delay(captureDelay);
		target.addEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
	}
	private function addToStageHandler(event:Event):void{
		_target.removeEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
		if (_totalNum == 0){
			_handler();
			return;
		}
		// 素材ロードの開始
		for each (var assetData:AssetData in _assetList){
			assetData.loadStart();
		}
	}
	
	private function loadComplete(event:Event):void{
		trace("loadComplete");
		_completeNum++;
		if (_totalNum <= _completeNum){
			_handler();
		}
	}
	private function loadError(event:IOErrorEvent):void{
		throw new Error(event.toString());
	}
	
	public function getAsset(id:String):AssetData{
		return _assetList[id];
	}
	
}
/* 素材ロードテンプレート*/
class AssetData{
	private var _url:String;
	private var _id:String;
	private var _type:String;
	private var _handler:Function;
	private var _errorHandler:Function;
	
	private var _loader:Loader;
	private var _urlLoader:URLLoader;
	
	public static const TYPE_IMAGE:String = "type image";
	public static const TYPE_SWF:String = "type swf";
	public static const TYPE_TEXT:String = "type text";
	
	public function AssetData(url:String, id:String, type:String, handler:Function, errorHandler:Function){
		_url = url;
		_id = id;
		_type = type;
		_handler = handler;
		_errorHandler = errorHandler;
	}
	public function loadStart():void{
		loadClose();
		trace("loadStart");
		var request:URLRequest = new URLRequest(_url);
		switch(_type){
			case TYPE_IMAGE :
			case TYPE_SWF :{
				_loader = new Loader();
				_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _handler);
				_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _errorHandler);
				_loader.load(request);
			}break;
			case TYPE_TEXT :{
				_urlLoader = new URLLoader();
				_urlLoader.addEventListener(Event.COMPLETE, _handler);
				_urlLoader.addEventListener(IOErrorEvent.IO_ERROR, _errorHandler);
				_urlLoader.load(request);
			}break;
		}
	}
	private function loadClose():void{
		try{
			if (_loader != null){
				_loader.close();
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, _handler);
				_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, _errorHandler);
			}
			if (_urlLoader != null){
				_urlLoader.close();
				_urlLoader.removeEventListener(Event.COMPLETE, _handler);
				_urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, _errorHandler);
			}
		}catch (error:Error){}
	}
	public function getBitmapData():BitmapData{
		return Bitmap(_loader.content).bitmapData;
	}
	public function getString():String{
		return String(_urlLoader.data);
	}
	public function getSprite():Sprite{
		return Sprite(_loader.content);
	}
}