くまの人メイカー(全自動版)
1. イケてる自分の顔をwebカメラに映す。
2. SAVEボタンではいチーズ!
ほんとはsaqooshaさんのクマ帽子の画像でやりたいけど画像ない・・・
↓
くまでやったよ!
スケールまわりだいぶ適当、とりあえずくまに変えただけ。ゴミだらけ。
顔ラボ:顔検出WebAPI仕様
http://kaolabo.com/webapi/spec
/**
* Copyright minon ( http://wonderfl.net/user/minon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/peDY
*/
// forked from fumix's あの人メイカー(全自動版)
// 1. イケてる自分の顔をwebカメラに映す。
// 2. SAVEボタンではいチーズ!
//
// ほんとはsaqooshaさんのクマ帽子の画像でやりたいけど画像ない・・・
// ↓
// くまでやったよ!
// スケールまわりだいぶ適当、とりあえずくまに変えただけ。ゴミだらけ。
//
// 顔ラボ:顔検出WebAPI仕様
// http://kaolabo.com/webapi/spec
package {
import com.bit101.components.PushButton;
import mx.graphics.codec.JPEGEncoder;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.media.Camera;
import flash.media.Video;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.system.LoaderContext;
import flash.text.TextField;
import flash.utils.ByteArray;
import flash.utils.Timer;
/**
* @author fumix
*/
[SWF(backgroundColor="#000000", frameRate="31", width="465", height="465")]
public class AnohitoMaker extends Sprite {
private var _camera : Camera;
private var _w : int;
private var _h : int;
private var _video : Video;
private var _startScale : Number;
private var _startPoint : Point;
private var _kuma : Sprite;
private var _megane : Sprite;
private var _referenceObject : Sprite;
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';
/**
* コンストラクタ
*/
public function AnohitoMaker() {
if (stage) initialize();
else addEventListener(Event.ADDED_TO_STAGE, initialize);
}
/**
* 初期化
* @param event
*/
private function initialize(event : Event = null) : void {
removeEventListener(Event.ADDED_TO_STAGE, initialize);
//プロパティの初期化
_startPoint = new Point();
//背景
_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 = 'カメラ無し';
addChild(txt);
}
//あの画像読み込み
var url : String = "http://labs.minomix.net/kuma/kuma.png";
var loader : Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
loader.load(new URLRequest(url), new LoaderContext(true));
//保存ボタン
_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();
}
/**
* 顔認識APIリクエスト
*/
private function requestAPIFacialRecognition() : void {
//画像バイナリ生成
var cap : BitmapData = new BitmapData(_w, _h);
cap.draw(_video);
var enc : JPEGEncoder = new JPEGEncoder(80);
var byteArray : ByteArray = enc.encode(cap);
addChild(new Bitmap(cap));
//POSTリクエスト生成
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 {
//スコア
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 megane_width:Number = 55;
var megane_distX:Number = (faces[0].elements('left-eye').@x - faces[0].elements('right-eye').@x);
var megane_distY:Number = (faces[0].elements('left-eye').@y - faces[0].elements('right-eye').@y);
var megane_dist:Number = Math.sqrt(megane_distX * megane_distX+megane_distY*megane_distY);
var megane_scale:Number = megane_dist / megane_width;
_kuma.scaleX = _kuma.scaleY = megane_scale;
_kuma.x = Number(faces[0].elements('right-eye').@x) + (faces[0].elements('left-eye').@x - faces[0].elements('right-eye').@x)/ 2;
_kuma.y = Number(faces[0].@y)+Number(faces[0].@height)*0.8;
addChild(_kuma);
}
/**
* 名前空間を削除します
* @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();
}
}
/**
* 画像読み込み完了
* @param event
*/
private function loadCompleteHandler(event : Event) : void {
var content : Bitmap = LoaderInfo(event.target).content as Bitmap;
var bmd : BitmapData = content.bitmapData;
var bmd_kuma : BitmapData = new BitmapData(320, 320, true, 0x00FFFFFF);
//くま
bmd_kuma.draw(bmd);
var bm_kuma : Bitmap = new Bitmap(bmd_kuma);
bm_kuma.x = -bm_kuma.width / 2;
bm_kuma.y = -bm_kuma.height / 1.23;
_kuma = new Sprite();
_kuma.addChild(bm_kuma);
}
/**
* 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);
}
}
}