<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:controls="com.dougmccune.controls.*" viewSourceURL="srcview/index.html" creationComplete="initDetector()" width="640" height="480"> <mx:Script> <![CDATA[ import com.dougmccune.safeSexting.BlackoutEyesFilter; import com.dougmccune.safeSexting.BlurFaceFilter; import com.dougmccune.safeSexting.MosaicFilter; import mx.graphics.ImageSnapshot; import mx.collections.ArrayCollection; import com.dougmccune.safeSexting.IFaceFilter; import com.dougmccune.face.MarilenaDetector; private var mDetector:MarilenaDetector; private var faceFilter:IFaceFilter; [Bindable] public var snapshots:ArrayCollection = new ArrayCollection(); private function initDetector():void{ mDetector = new MarilenaDetector(); mDetector.foundCallback = faceFound; mDetector.notFoundCallback = faceNotFound; mDetector.smoothMovement = false; invalidateDisplayList(); } private function faceNotFound():void { error.visible = true; } private function setFaceFilter(newFilter:IFaceFilter):void { faceFilter = newFilter; if(faceFilter) { mDetector.startDetecting(); faceOverlay.visible = true; faceFilter.applyFilter(faceCam, faceOverlay); faceFilter.runFilter(faceCam, faceOverlay, mDetector.lastPercentageRectangle); } else { faceCam.filters = []; faceOverlay.visible = false; mDetector.stopDetecting(); } } private function faceFound():void { error.visible = false; if(faceFilter) { faceFilter.runFilter(faceCam, faceOverlay, mDetector.lastPercentageRectangle); } faceMask.graphics.clear(); faceMask.graphics.lineStyle(1, 0xff0000); faceMask.graphics.beginFill(0); faceMask.graphics.drawEllipse(width * mDetector.lastPercentageRectangle.x, height * mDetector.lastPercentageRectangle.y, mDetector.lastPercentageRectangle.width * width, mDetector.lastPercentageRectangle.height * height); faceMask.graphics.endFill(); } private function filterBar_clickHandler(event:Event):void { setFaceFilter(filterBar.dataProvider[filterBar.selectedIndex].filter); } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { if(stage) stage.quality = StageQuality.MEDIUM; super.updateDisplayList(unscaledWidth, unscaledHeight); if(mDetector && mDetector.lastPercentageRectangle != null) { faceFound(); } } private function sendButton_clickHandler(event:Event):void { countdown.text = "3"; countdown.visible = true; sendButton.enabled = false; var timer:Timer = new Timer(1000, 3); timer.addEventListener(TimerEvent.TIMER, timerHandler); timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHandler); timer.start(); } private function timerHandler(event:TimerEvent):void { countdown.text = String(Number(countdown.text) - 1); } private function timerCompleteHandler(event:TimerEvent):void { countdown.text = "3"; countdown.visible = false; sendButton.enabled = true; var bitmapData:BitmapData = ImageSnapshot.captureBitmapData(captureCanvas); var m:Matrix = new Matrix(); var scale:Number = 90/bitmapData.width; m.scale(scale, scale); var thumb:BitmapData = new BitmapData(bitmapData.width*scale, bitmapData.height*scale, false); thumb.draw(bitmapData, m); snapshots.addItem({thumb:new Bitmap(thumb), snapshot:new Bitmap(bitmapData)}); } public function cloneBitmap(bitmap:Bitmap):Bitmap { return new Bitmap(bitmap.bitmapData.clone()); } ]]> </mx:Script> <mx:Style source="assets/style.css" /> <mx:Array id="possibleFilters"> <mx:Object id="none" icon="@Embed('/assets/icon_none.png')" /> <mx:Object id="mosaic" filter="{new MosaicFilter()}" icon="@Embed('/assets/icon_mosaic.png')" /> <mx:Object id="blur" filter="{new BlurFaceFilter()}" icon="@Embed('/assets/icon_blur.png')"/> <mx:Object id="blackEyes" filter="{new BlackoutEyesFilter()}" icon="@Embed('/assets/icon_blackbar.png')"/> </mx:Array> <mx:VBox width="100%" height="100%" verticalGap="0" verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:Canvas width="100%" height="100%" verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:Canvas id="captureCanvas" width="100%" height="100%" verticalScrollPolicy="off" horizontalScrollPolicy="off"> <controls:WebcamDisplay width="100%" height="100%" maintainAspectRatio="true" mirror="true" /> <controls:WebcamDisplay id="faceCam" width="100%" height="100%" maintainAspectRatio="true" mask="{faceMask}" mirror="true" /> <mx:UIComponent id="faceMask" /> <mx:Canvas id="faceOverlay" width="100%" height="100%" /> </mx:Canvas> <mx:VBox styleName="errorBox" visible="false" id="error"> <mx:Label text="Can't find a face" /> </mx:VBox> <mx:VBox horizontalCenter="0" bottom="10" horizontalAlign="center"> <mx:ToggleButtonBar id="filterBar" dataProvider="{possibleFilters}" itemClick="filterBar_clickHandler(event)" /> <mx:Button label="Say Cheese" id="sendButton" styleName="greenButton" click="sendButton_clickHandler(event)" /> </mx:VBox> <mx:Label id="countdown" styleName="countdown" visible="false" horizontalCenter="0" verticalCenter="0"> <mx:filters> <mx:GlowFilter color="#ffffff" /> <mx:DropShadowFilter /> </mx:filters> </mx:Label> <mx:Canvas width="100%" height="100%" backgroundColor="#000000" visible="{snapshotHolder.selectedIndex != -1}"> <mx:Image width="100%" height="100%" id="img" verticalAlign="middle" horizontalAlign="center" source="{cloneBitmap(snapshotHolder.selectedItem.snapshot as Bitmap)}" /> <mx:Button label="Close" styleName="greenButton" click="img.source = null; snapshotHolder.selectedIndex = -1" bottom="5" horizontalCenter="0" /> </mx:Canvas> </mx:Canvas> <mx:HorizontalList dataProvider="{snapshots}" includeInLayout="{snapshots.length != 0}" backgroundColor="#333333" width="100%" id="snapshotHolder" borderStyle="none" height="90" selectedIndex="-1"> <mx:itemRenderer> <mx:Component> <mx:Canvas borderStyle="solid" borderColor="#ffffff" backgroundColor="#000000"> <mx:Image source="{outerDocument.cloneBitmap(data.thumb)}" width="90" height="90" verticalAlign="middle" horizontalAlign="center" /> </mx:Canvas> </mx:Component> </mx:itemRenderer> </mx:HorizontalList> </mx:VBox> </mx:Application>