as3版かまいたちの夜カメラ
特に習作というわけでもないのだけれど、前に作ったかまいたちの夜カメラをas3で書いてみた。
クリックすると映像を固定。
以後、差分がいわゆるかまいたち。
上下キーでスレッショルド調整ができるけど、おまけ程度。
ほんとこれが ustream 配信できれば面白いのにな。
仮想カメラデバイスなソフトを作るスキルなんてないので残念。
あまり美しくないけど、ソースは以下。
よくよく考えたら今までソース丸ごと公開したことなかった気がする。
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Camera;
import flash.media.Video;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.Timer;
[SWF(backgroundColor=0x000000, frameRate='30', width='320', height='240')]
public class KamaCamera extends Sprite {
private const CAMERA_W:int = 320;
private const CAMERA_H:int = 240;
private const COLOR_SILHOUETTE:uint = 0x603300cc;
private const DEFAULT_THRESHOLD:uint = 0x20;
private var camera:Camera;
private var video:Video;
private var rect:Rectangle;
private var zero:Point;
private var mtx:Matrix;
private var threshold:uint;
private var threshold_txt:TextField;
private var timer:Timer;
private var temp_bd:BitmapData;
private var fixed_bd:BitmapData;
private var kama_bd:BitmapData;
public function KamaCamera() {
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.BEST;
stage.scaleMode = StageScaleMode.NO_SCALE;
timer = new Timer( 1000, 1 );
timer.addEventListener( TimerEvent.TIMER_COMPLETE, timerHandler );
camera = Camera.getCamera();
if ( camera != null ) {
setup();
}
}
private function setup():void {
var format:TextFormat = new TextFormat( null, 120, 0xffffff );
format.align = "center";
threshold_txt = new TextField();
threshold_txt.mouseEnabled = false;
threshold_txt.autoSize = TextFieldAutoSize.CENTER;
threshold_txt.defaultTextFormat = format;
threshold_txt.text = String( threshold );
threshold_txt.x = ( CAMERA_W - threshold_txt.width ) / 2;
threshold_txt.y = ( CAMERA_H - threshold_txt.height ) / 2;
threshold_txt.visible = false;
setThreshold( DEFAULT_THRESHOLD );
video = new Video( CAMERA_W, CAMERA_H );
video.attachCamera( camera );
addChild( video );
rect = new Rectangle( 0, 0, CAMERA_W, CAMERA_H );
zero = new Point();
mtx = new Matrix();
temp_bd = new BitmapData( CAMERA_W, CAMERA_H, true, 0x00000000 );
fixed_bd = temp_bd.clone();
kama_bd = temp_bd.clone();
var func:Function = function( e:MouseEvent ):void {
fix();
update();
removeChild( video );
addChild( new Bitmap( kama_bd ) );
addChild( threshold_txt );
stage.removeEventListener( e.type, arguments.callee );
stage.addEventListener( MouseEvent.CLICK, fix );
stage.addEventListener( Event.ENTER_FRAME, update );
stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );
}
stage.addEventListener( MouseEvent.CLICK, func );
}
private function fix( e:MouseEvent = null ):void {
fixed_bd.draw( video );
}
private function update( e:Event = null ):void {
temp_bd.copyPixels( fixed_bd, rect, zero );
temp_bd.draw( video, mtx, null, "subtract");
temp_bd.threshold( temp_bd, rect, zero, ">", threshold << 16, COLOR_SILHOUETTE, 0x00FF0000, false );
temp_bd.threshold( temp_bd, rect, zero, ">", threshold << 8, COLOR_SILHOUETTE, 0x0000FF00, false );
temp_bd.threshold( temp_bd, rect, zero, ">", threshold, COLOR_SILHOUETTE, 0x000000FF, false );
temp_bd.threshold( temp_bd, rect, zero, "==", 0xff000000, 0x00000000, 0xFF000000, false );
kama_bd.lock();
kama_bd.copyPixels( fixed_bd, rect, zero );
kama_bd.draw( temp_bd );
kama_bd.unlock();
}
private function setThreshold( value:int ):void {
threshold = Math.min( Math.max( value, 0x00 ), 0xff );
threshold_txt.text = String( threshold );
threshold_txt.visible = true;
timer.reset();
timer.start();
}
private function keyDownHandler( e:KeyboardEvent ):void {
switch ( e.keyCode ) {
case Keyboard.UP:
setThreshold( threshold + 1 );
break;
case Keyboard.DOWN:
setThreshold( threshold - 1 );
break;
}
}
private function timerHandler( e:TimerEvent ):void {
threshold_txt.visible = false;
}
}
}


