forked from: 色要素の分解
@author tail
/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3fwk
*/
// forked from tail_y's 色要素の分解
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 _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(_bmd);
}
// パレット作成
private function start( bmd:BitmapData, _shortRate:int=7, _whiteLine:int = 0xf3 ):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++) {// x
for (var pointY:int = 0; pointY < _size; pointY++) {// y
color = bmd.getPixel(pointX, pointY);//imgから色取得
//3原色に分解
r = (color >> 16) & 0xFF;//赤成分
g = (color >> 8) & 0xFF;//緑成分
b = (color) & 0xFF;//青成分
//減色して再合成
shortColor = (r >> _shortRate) << 16;//* 0x100;
shortColor+= (g >> _shortRate) << 8;//* 0x10;
shortColor+= (b >> _shortRate);
min = Math.min(r, g, b);//3原色のうち最も小さい値を取得
max = Math.max(r, g, b);//最も大きい(ry
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++;//カウントアップ
}
}// y
}// x
// パレット数がいくつになったか
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, _whiteLine:int = 0xf3 ):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);
}
}