PsychedelicCam @author fumix fumix forked:0favorite:9lines:158license : MIT License modified : 2010-07-26 14:25:38 Embed Tweet package { import net.hires.debug.Stats; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.ColorMatrixFilter; import flash.filters.ConvolutionFilter; import flash.geom.Point; import flash.geom.Rectangle; import flash.media.Camera; import flash.media.Video; import flash.text.TextField; /** * @author fumix */ [SWF(backgroundColor="#000000", frameRate="31", width="465", height="465")] public class PsychedelicCam extends Sprite { private var _w : int; private var _h : int; private var _camera : Camera; private var _video : Video; private var _bm : Bitmap; private var _bmd : BitmapData; private var _psycheFlag : Boolean; public function PsychedelicCam() { 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); //背景設定 _w = stage.stageWidth; _h = stage.stageHeight; var bmd : BitmapData = new BitmapData(_w, _h, true, 0x000000); addChild(new Bitmap(bmd)); //webカメラ _camera = Camera.getCamera(); _camera.setMode(_w, _h, 15); _video = new Video(_w, _h); _video.attachCamera(_camera); addChild(_video); //カメラあり if(_camera != null) { //カメラ無し } else { var txt : TextField = new TextField(); txt.textColor = 0xFFFFFF; txt.text = 'カメラ無し'; addChild(txt); } //フラグ初期化 _psycheFlag = false; //サイケ画像表示用 _bm = new Bitmap(); _bmd = new BitmapData(_w, _h, true, 0xFFFFFFFF); _bm.bitmapData = new BitmapData(_w, _h, true, 0xFF000000); _bm.visible = false; addChild(_bm); //Stats addChild(new Stats()); Wonderfl.capture_delay( 20 ); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); } /** * マウスクリック * @param event */ private function onMouseUp(event : MouseEvent) : void { _psycheFlag = !_psycheFlag; if(_psycheFlag) { _bm.visible = true; effect(); //stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); }else{ _bm.visible = false; //stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame); } } /** * フレーム処理 * @param event */ private function onEnterFrame(event : Event) : void { effect(); } /** * エフェクト処理 */ private function effect() : void { var colorArray : Array = [0xFF33CC33,0xFF3364FE,0xFFC727F9,0xFFFF4342,0xFFFFFF02,0xFF658448,0xFFFE33A8]; colorArray = shuffleArray(colorArray); var bmd : BitmapData = new BitmapData(_w, _h); var thres : BitmapData; var edge : BitmapData; var min : int = 20; var max : int = 190; var step : int = 7; //ベースのbitmapをリセット _bm.bitmapData.copyPixels(_bmd, _bmd.rect, new Point(0, 0)); //webカメラの画像を取得 bmd.draw(_video); //グレースケール化 var t:Number var g : BitmapData = grayscaleFilter(bmd); //ノイズ除去 g = medianSmoothFilter(g); for (var i : int = 0;i <step;i ++) { t= min+(max-min)/step * i; //2値化 thres = thresholdFilter(g, t, colorArray[i]); //2値化 edge = thresholdFilter(g, t); //エッジ検出 edge = laplacianFilter(edge); //描画 _bm.bitmapData.draw(thres, null, null, BlendMode.NORMAL); _bm.bitmapData.draw(edge, null, null, BlendMode.SUBTRACT); } //ビットマップ破棄 bmd.dispose(); thres.dispose(); edge.dispose(); } /** * 2値化処理 * @param image * @param threshold * @param color * @return BitmapData */ private function thresholdFilter(image : BitmapData,threshold : int,color : uint = 0xFFFFFFFF) : BitmapData { var d:BitmapData = new BitmapData(image.width, image.height); var r:Rectangle = new Rectangle(0, 0, image.width, image.height); d.fillRect(r, 0x00000000); // 不透明黒で塗りつぶす // 閾値以下を不透明黒にする d.threshold(image, r, new Point(0, 0), ">", threshold, color, 0x000000FF, false); return d; } /** * ノイズ除去 * @param image * @return BitmapData */ private function medianSmoothFilter(image : BitmapData) : BitmapData { var d:BitmapData = new BitmapData(image.width, image.height); var a:Array = new Array(9); for (var x:int = 0; x < image.width; x++) { for (var y:int = 0; y < image.height; y++) { a[0] = image.getPixel(x - 1, y - 1) & 255; a[1] = image.getPixel(x - 1, y) & 255; a[2] = image.getPixel(x - 1, y + 1) & 255; a[3] = image.getPixel(x, y - 1) & 255; a[4] = image.getPixel(x, y) & 255; a[5] = image.getPixel(x, y + 1) & 255; a[6] = image.getPixel(x + 1, y - 1) & 255; a[7] = image.getPixel(x + 1, y) & 255; a[8] = image.getPixel(x + 1, y + 1) & 255; a.sort(Array.NUMERIC); // ソートして var c:int = a[4]; // 真ん中を取る d.setPixel(x, y, (c << 16) | (c << 8) | c); // 中央値による色の設定 } } return d; } /** * ラプラシアンフィルタ(エッジ処理) * @param image * @return BitmapData */ private function laplacianFilter(image : BitmapData) : BitmapData { var d:BitmapData = new BitmapData(image.width, image.height); var rect : Rectangle = new Rectangle(0, 0, image.width, image.height); var p : Point = new Point(0, 0); var l:Array = [-1, -1, -1, -1, +8, -1, -1, -1, -1]; // ラプラシアンフィルタ d.applyFilter(image, rect, p, new ConvolutionFilter(3, 3, l)); return d; } /** * グレースケールフィルタ * @param imageData * @return BitmapData * @return BitmapData */ private function grayscaleFilter(image : BitmapData) : BitmapData { var d : BitmapData = new BitmapData(image.width, image.height); var rect : Rectangle = new Rectangle(0, 0, image.width, image.height); var p : Point = new Point(0, 0); var cmatrix:ColorMatrixFilter = new ColorMatrixFilter([ 1/3,1/3,1/3,0 ,0, 1/3,1/3,1/3,0 ,0, 1/3,1/3,1/3,0 ,0, 0 ,0 ,0 ,255,0]); d.applyFilter(image, rect, p, cmatrix); return d; } /** * 配列のシャッフル * @param arr * @return Array */ private function shuffleArray(arr:Array):Array { var _len:uint = arr.length; var _reArr:Array = arr; while (_len) { var _m:uint = Math.floor(Math.random() * _len); var _n:uint = _reArr[--_len]; _reArr[_len] = _reArr[_m]; _reArr[_m] = _n ; } return _reArr; } } } Code Fullscreen Preview Fullscreen 画面クリックでエフェクト?の切り替え by fumix at 2010/07/24 06:18:25 すごい重いのでEnterFrame内でエフェクトかけるのは止めた方が良かったかもしれない・・・ by fumix at 2010/07/24 06:21:14 EnterFrameでエフェクトかけるのやめて、クリックでエフェクトかかった静止画を出すように変更。 by fumix at 2010/07/25 15:35:35 ノイズ除去処理を追加した。 by fumix at 2010/07/26 14:26:48 msmdk rettuce tjoen siouxcitizen.. kidaipu novita001 quinten : psychidelisch iki_xx : camera hacker_rs10v.. : bitmap effect camera webカメラ height width visible Rectangle color Video Math.min MouseEvent.ADDED_TO_STAGE stage Math.max addChild ConvolutionFilter attachCamera sort Array.NUMERIC removeEventListener Stats textColor addEventListener MouseEvent.MOUSE_UP