わんだふりゃーイケメンランキング
顔ラボのwebapiを使ったイケメン判定機能(?)
wonderflerのなかでだれが一番イケメンなのか!
使い方:
1. イケてる自分の顔をwebカメラに映す。
2. captureボタンではいチーズ! カウントダウン後キャプチャ。
3. イケメンランキング表示!
顔ラボ:顔検出WebAPI仕様
http://kaolabo.com/webapi/spec
wonderfl:ScoreRankingAPI
http://wonderfl.net/code/797401b934b64961187ba280eb371454e82a59c1
/**
* 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");
}
}