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

わんだふりゃーイケメンランキング

顔ラボのwebapiを使ったイケメン判定機能(?)
wonderflerのなかでだれが一番イケメンなのか!
使い方:
1. イケてる自分の顔をwebカメラに映す。
2. captureボタンではいチーズ! カウントダウン後キャプチャ。
3. イケメンランキング表示!
顔ラボ:顔検出WebAPI仕様
http://kaolabo.com/webapi/spec
wonderfl:ScoreRankingAPI
http://wonderfl.net/code/797401b934b64961187ba280eb371454e82a59c1
Get Adobe Flash player
by fumix 07 Apr 2010
/**
 * Copyright fumix ( http://wonderfl.net/user/fumix )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/W6GN
 */

// 顔ラボのwebapiを使ったイケメン判定機能(?)
// wonderflerのなかでだれが一番イケメンなのか!
// 使い方:
// 1. イケてる自分の顔をwebカメラに映す。
// 2. captureボタンではいチーズ! カウントダウン後キャプチャ。
// 3. イケメンランキング表示!
//
// 顔ラボ:顔検出WebAPI仕様
// http://kaolabo.com/webapi/spec
// wonderfl:ScoreRankingAPI
// http://wonderfl.net/code/797401b934b64961187ba280eb371454e82a59c1
package {
	import flash.system.Security;

	import com.bit101.components.PushButton;

	import mx.graphics.codec.JPEGEncoder;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	import flash.utils.Timer;

	import net.wonderfl.score.basic.BasicScoreForm;
	import net.wonderfl.score.basic.BasicScoreRecordViewer;

	/**
	 * @author fumix
	 */
	[SWF(backgroundColor="#000000", frameRate="31", width="465", height="465")]

	public class IkemenRanking extends Sprite {

		private var _camera : Camera;
		private var _w : int;
		private var _h : int;
		private var _video : Video;
		private var _btn : PushButton;
		private var _timer : Timer;
		private var _count : int;
		private var _xml : XML;

		private const APIURL : String = 'http://www.planet-ape.net/wonderfl/kaolabo.php';

		private var _form:BasicScoreForm;

		/**
		 * コンストラクタ
		 */
		public function IkemenRanking() {
			if (stage) initialize();
			else addEventListener(Event.ADDED_TO_STAGE, initialize);			
		}

		/**
		 * 初期化
		 * @param event 
		 */
		private function initialize(event : Event = null) : void {
           // don't take a capture
            Wonderfl.disable_capture();
            
            	removeEventListener(Event.ADDED_TO_STAGE, initialize);
			//背景
			_w = stage.stageWidth;
			_h = stage.stageHeight;
			var bmd : BitmapData = new BitmapData(_w, _h, true, 0x000000);
			addChild(new Bitmap(bmd));
			
			//webカメラ
			_camera = Camera.getCamera();

			//カメラあり
			if(_camera != null) {
				setupCamera();
            //カメラ無し
			} else {
				var txt : TextField = new TextField();
				txt.textColor = 0xFFFFFF;
				txt.text = 'カメラ無し';
				txt.x = _w/2 - txt.width/2;
				txt.y = _h /2 - txt.height/2;
				addChild(txt);
			}
			//保存ボタン
			_btn = new PushButton(this, 0, 0, 'capture', buttonClickHandler);
		}

		/**
		 * ボタンクリック
		 * @param event
		 */
		private function buttonClickHandler(event : MouseEvent) : void {
			//タイマーハンドラ(カウントダウン)
			_count = 3;
			_btn.label = String(_count);
			_timer = new Timer(1000, 3);
			_timer.addEventListener(TimerEvent.TIMER, timerHandler);
			_timer.start();
			//requestAPIFacialRecognition();				
		}

		/**
		 * 顔認識APIリクエスト
		 */
		private function requestAPIFacialRecognition() : void {
			//画像バイナリ生成
			var cap : BitmapData = new BitmapData(_w, _h);
			cap.draw(_video);
			addChild(new Bitmap(cap));

			//POSTリクエスト生成(jpegデータ)
			var enc : JPEGEncoder = new JPEGEncoder(80);
			var byteArray : ByteArray = enc.encode(cap);
			var request : URLRequest = new URLRequest(APIURL);
			request.method = URLRequestMethod.POST;
			request.contentType = "image/jpeg";
			request.data = byteArray;
			
			//リクエスト用ローダー生成
			var loader : URLLoader = new URLLoader(request);
			loader.addEventListener(Event.COMPLETE, onLoaderComplate);
			//リクエスト実行
			loader.load(request);
		}

		/**
		 * リクエスト実行完了
		 * @param event
		 */
		private function onLoaderComplate(event : Event) : void {
            // take a capture after 5 sec
            Wonderfl.capture_delay( 5 );

            			//スコア
			var score:Number = 0;
			//戻り値
			_xml = deleteNameSpace(event.target.data);
			var faces : XMLList = _xml.faces[0].face;
			//顔認識されなかった場合
			if(faces.length() < 1){
				var txt : TextField = new TextField();
				txt.textColor = 0xFFFFFF;
				txt.text = 'no faces!';
				addChild(txt);
				return;
			}

			//顔認識結果を描画するためのスプライトを設置
			var faceRect : Sprite = new Sprite();
			addChild(faceRect);
			faceRect.graphics.lineStyle(1, 0xFF0000);
			//認識した顔の個数分ループ
			for (var i : String in faces) {
				faceRect.graphics.drawRect(faces[i].@x, faces[i].@y, faces[i].@width, faces[i].@height);
				faceRect.graphics.drawCircle(faces[i].elements('left-eye').@x, faces[i].elements('left-eye').@y, 10);
				faceRect.graphics.drawCircle(faces[i].elements('right-eye').@x, faces[i].elements('right-eye').@y, 10);
				score += faces[i].@score;
			}
            
			//スコアを平均化
			score = score / faces.length();
			//twitterポスト
//			var twitterPostButton:TwitterButton = new TwitterButton('http://hogehoge');
//			twitterPostButton.changeText("イケメンスコア:" + score);
			_form = new BasicScoreForm(this, (_w-BasicScoreForm.WIDTH)/2, (_h-BasicScoreForm.HEIGHT)/2, score, 'SAVE SCORE', showRanking);

		}
		private function showRanking($didSavedScore:Boolean):void {
			// removes form
			removeChild(_form);
			
			var ranking:BasicScoreRecordViewer = new BasicScoreRecordViewer(this, (_w-BasicScoreRecordViewer.WIDTH)/2,(_h-BasicScoreRecordViewer.HEIGHT)/2,'RANKING', 99, true);
		}

		/**
		 * 名前空間を削除します
		 * @param	オリジナルストリング(XML形式)
		 * @return	namespace宣言を取り去ったXML
		 */
		private function deleteNameSpace(xmlText : String) : XML {
			// remove the namespaces from the string representation of the XML
			xmlText = xmlText.replace(new RegExp("xmlns[^\"]*\"[^\"]*\"", "gi"), "");
			xmlText = xmlText.replace(new RegExp("xsi[^\"]*\"[^\"]*\"", "gi"), "");

			// set the string rep. of the XML back to real XML
			return new XML(xmlText);
		}

		/**
		 * タイマーハンドラ(カウントダウン)
		 * @param event
		 */
		private function timerHandler(event : TimerEvent) : void {
			_count--;
			_btn.label = String(_count);
			if(_count == 0) {
				_btn.visible = false;
				requestAPIFacialRecognition();				
			}			
		}

		
		
		/**
		 * webカメラセットのアップ
		 */
		private function setupCamera() : void {
			_camera.setMode(Math.floor(_w / 2), Math.floor(_h / 2), 15);
			_video = new Video(_w, _h);
			_video.attachCamera(_camera);
			addChild(_video);
		}
	}
}


// ここから下をコピペしてください

import flash.utils.escapeMultiByte;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.events.MouseEvent;
import flash.display.DisplayObjectContainer;
import com.bit101.components.PushButton;

class TwitterButton extends PushButton {
	private var _text:String;
	private var _footer:String;
	public function changeText(str:String = ""):void { _text = str; }
	
	public function TwitterButton(linkURL:String, parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, text:String = "", hashTag:String = "#wonderfl") {
		super(parent, xpos, ypos, "Post to Twitter", postToTwitter);
		changeText(text);
		_footer = " " + linkURL + " " + hashTag;
		this.scaleX = this.scaleY = 1.5;
	}
	
	private function postToTwitter(e:MouseEvent):void {
		var post:String = _text + _footer; // 投稿する文章
		navigateToURL(new URLRequest("http://twitter.com/home?status=" + escapeMultiByte(post)), "_blank");
	}
}