Last active
April 28, 2016 23:21
-
-
Save marchbold/0075bbf8ccf46ac76668 to your computer and use it in GitHub Desktop.
A Basic Starling Camera UI using the distriqt Camera ANE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* __ __ __ | |
* ____/ /_ ____/ /______ _ ___ / /_ | |
* / __ / / ___/ __/ ___/ / __ `/ __/ | |
* / /_/ / (__ ) / / / / / /_/ / / | |
* \__,_/_/____/_/ /_/ /_/\__, /_/ | |
* / / | |
* \/ | |
* http://distriqt.com | |
* | |
* @file VideoCameraUI.as | |
* @brief A Basic Starling Camera UI using the distriqt Camera ANE | |
* @author "Michael Archbold (ma@distriqt.com)" | |
* @created 30/03/2015 | |
* @copyright http://distriqt.com/copyright/license.txt | |
*/ | |
package com.distriqt.camera.starling | |
{ | |
import com.distriqt.extension.camera.Camera; | |
import com.distriqt.extension.camera.CameraMode; | |
import com.distriqt.extension.camera.CameraParameters; | |
import com.distriqt.extension.camera.CaptureDevice; | |
import com.distriqt.extension.camera.events.CameraEvent; | |
import flash.desktop.NativeApplication; | |
import flash.display.BitmapData; | |
import flash.display3D.textures.Texture; | |
import flash.events.Event; | |
import flash.geom.Matrix; | |
import flash.geom.Rectangle; | |
import flash.utils.ByteArray; | |
import starling.display.Image; | |
import starling.display.Sprite; | |
import starling.events.Event; | |
import starling.textures.Texture; | |
/** | |
* @author "Michael Archbold (ma@distriqt.com)" | |
*/ | |
public class VideoCameraUI extends Sprite | |
{ | |
/** | |
* Constructor | |
*/ | |
public function VideoCameraUI() | |
{ | |
super(); | |
addEventListener( starling.events.Event.ADDED_TO_STAGE, addedToStageHandler ); | |
} | |
//////////////////////////////////////////////////////// | |
// VARIABLES | |
// | |
private var _options : CameraParameters | |
private var _device : CaptureDevice; | |
private var _container : Sprite; | |
private var _preview : Image; | |
private var _previewTexture : starling.textures.Texture; | |
private var _previewData : ByteArray; | |
private var _previewBitmapData : BitmapData; | |
private var _previewBitmapRect : Rectangle; | |
private var _lastFrameProcessed : Number = -1; | |
//////////////////////////////////////////////////////// | |
// FUNCTIONALITY | |
// | |
//////////////////////////////////////////////////////// | |
// INTERNALS | |
// | |
private function initialiseExtension():void | |
{ | |
try | |
{ | |
Camera.init( Config.APP_KEY ); | |
if (Camera.isSupported) | |
{ | |
var devices:Array = Camera.instance.getAvailableDevices(); | |
for each (var device:CaptureDevice in devices) | |
{ | |
if (device.position == CaptureDevice.POSITION_FRONT) | |
{ | |
_device = device; | |
break; | |
} | |
} | |
_options = new CameraParameters(); | |
_options.enableFrameBuffer = true; | |
_options.cameraMode = new CameraMode( CameraMode.PRESET_HIGH ); | |
_options.deviceId = _device.id; | |
_options.frameBufferWidth = 1280; | |
_options.frameBufferHeight = 720; | |
Camera.instance.addEventListener( CameraEvent.VIDEO_FRAME, camera_videoFrameHandler ); | |
Camera.instance.initialise( _options ); | |
Camera.instance.setFocusMode( CameraParameters.FOCUS_MODE_CONTINUOUS ); | |
} | |
} | |
catch (e:Error) | |
{ | |
trace( e ); | |
} | |
} | |
private function releaseExtension():void | |
{ | |
try | |
{ | |
Camera.instance.removeEventListener( CameraEvent.VIDEO_FRAME, camera_videoFrameHandler ); | |
Camera.instance.release(); | |
Camera.instance.dispose(); | |
} | |
catch (e:Error) | |
{ | |
trace( e ); | |
} | |
} | |
private function DEG2RAD( degrees:Number ):Number | |
{ | |
return degrees * Math.PI / 180; | |
} | |
//////////////////////////////////////////////////////// | |
// EVENT HANDLERS | |
// | |
private function addedToStageHandler( event:starling.events.Event ):void | |
{ | |
_previewData = new ByteArray(); | |
_previewBitmapData = new BitmapData( 1, 1, false ); | |
_previewBitmapRect = new Rectangle(0,0,1,1); | |
_previewTexture = starling.textures.Texture.fromBitmapData( _previewBitmapData ); | |
_preview = new Image( _previewTexture ); | |
addChild( _preview ); | |
initialiseExtension(); | |
NativeApplication.nativeApplication.addEventListener( flash.events.Event.DEACTIVATE, deactivateHandler ); | |
NativeApplication.nativeApplication.addEventListener( flash.events.Event.ACTIVATE, activateHandler ); | |
} | |
private function deactivateHandler( event:flash.events.Event ):void | |
{ | |
releaseExtension(); | |
} | |
private function activateHandler( event:flash.events.Event ):void | |
{ | |
initialiseExtension(); | |
} | |
private function camera_videoFrameHandler( event:CameraEvent ):void | |
{ | |
var frame:Number = Camera.instance.receivedFrames; | |
if (frame != _lastFrameProcessed) | |
{ | |
if (-1 != Camera.instance.getFrameBuffer( _previewData )) | |
{ | |
try | |
{ | |
// | |
// Check we have an appropriately sized bitmapdata and texture | |
// Recreate if not | |
if (_previewBitmapData.width != Camera.instance.width || _previewBitmapData.height != Camera.instance.height) | |
{ | |
trace( "resizing to: (" + Camera.instance.width +", "+ Camera.instance.height +")" ); | |
_previewBitmapData.dispose(); | |
_previewTexture.dispose(); | |
_previewBitmapData = new BitmapData( Camera.instance.width, Camera.instance.height, false ); | |
_previewTexture = starling.textures.Texture.fromBitmapData( _previewBitmapData ); | |
_preview.texture = _previewTexture; | |
_preview.readjustSize(); | |
_previewBitmapRect = new Rectangle( 0, 0, _previewBitmapData.width, _previewBitmapData.height ); | |
var s:Number = 1.0; | |
var t:Matrix = new Matrix(); | |
if (_device.orientation == 90 || _device.orientation == 270) | |
{ | |
s = stage.stageWidth / _previewTexture.height; | |
t.translate( - _previewTexture.width * 0.5, - _previewTexture.height * 0.5 ); | |
t.rotate( DEG2RAD(_device.orientation) ); | |
t.scale( s, s ); | |
t.translate( _previewTexture.height * s * 0.5, _previewTexture.width * s * 0.5 ); | |
} | |
else | |
{ | |
s = stage.stageWidth / _previewTexture.width; | |
t.translate( - _previewTexture.width * 0.5, - _previewTexture.height * 0.5 ); | |
t.rotate( DEG2RAD(_device.orientation) ); | |
t.scale( s, s ); | |
t.translate( _previewTexture.width * s * 0.5, _previewTexture.height * s * 0.5 ); | |
} | |
// Something weird happens here with large bitmaps and it turns white? If you comment out this line it works but isn't rotated... | |
_preview.transformationMatrix = t; | |
} | |
// | |
// Update the bitmapdata and texture | |
_previewBitmapData.setPixels( _previewBitmapRect, _previewData ); | |
flash.display3D.textures.Texture(_previewTexture.base).uploadFromBitmapData( _previewBitmapData ); | |
} | |
catch (e:Error) | |
{ | |
trace( e ); | |
} | |
finally | |
{ | |
_previewData.clear(); | |
_lastFrameProcessed = frame; | |
} | |
} | |
} | |
} | |
} | |
} | |
// com.distriqt.Camera |
Great code, thaks very much!
To fix the White problem just need to set the generateMipMap false during the texture creation at line 197.
_previewTexture = starling.textures.Texture.fromBitmapData( _previewBitmapData, false );
I am also saving and applying the transformation matrix on a new bitmap data to return it as it looks.
var bd:BitmapData = new BitmapData(_preview.width, _preview.height, false, 0);
bd.draw(_previewBitmapData, _rotateMatrix);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please post your support questions in the github repository, we don't get notifications or follow these gists.