/* * PROJECT: FLARManager * http://transmote.com/flar * Copyright 2009, Eric Socolofsky * -------------------------------------------------------------------------------- * This work complements FLARToolkit, developed by Saqoosha as part of the Libspark project. * http://www.libspark.org/wiki/saqoosha/FLARToolKit * FLARToolkit is Copyright (C)2008 Saqoosha, * and is ported from NYARToolkit, which is ported from ARToolkit. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this framework; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For further information please contact: * * http://transmote.com/flar * */ package com.transmote.flar.source { 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.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.geom.Matrix; import flash.geom.Rectangle; import flash.net.URLRequest; /** * use the contents of a Loader as a source image for FLARToolkit marker detection. * FLARLoaderSource samples the contents of a Loader against a white background, * to provide maximum contrast for marker detection. * this class can be used for testing marker detection without a camera, * for example with a swf or jpeg with valid patterns within. * * @author Eric Socolofsky * @url http://transmote.com/flar */ public class FLARLoaderSource extends Sprite implements IFLARSource { private var _resultsToDisplayRatio:Number; private var loader:Loader; private var downsampleRatio:Number; private var displayWidth:Number; private var displayHeight:Number; private var displayBmpData:BitmapData; private var displayBitmap:Bitmap; private var displayMatrix:Matrix; private var sampleWidth:Number; private var sampleHeight:Number; private var sampleBmpData:BitmapData; private var sampleBitmap:Bitmap; private var sampleMatrix:Matrix; private var sampleMatRect:Rectangle; // area of sampleBmpData to fill with a white background before sending to FLARToolkit /** * constructor. * @param contentPath filename to load. * @param displayWidth width of source file. * @param displayHeight height of source file. * @param downsampleRatio amount to downsample camera input. * adjust to balance between image quality and marker tracking performance. * a value of 1.0 results in no downsampling; * a value of 0.5 (the default) downsamples the camera input by half. */ public function FLARLoaderSource (contentPath:String, displayWidth:Number, displayHeight:Number, downsampleRatio:Number=0.5) { this.downsampleRatio = downsampleRatio; this.displayWidth = displayWidth; this.displayHeight = displayHeight; this.sampleWidth = this.displayWidth * this.downsampleRatio; this.sampleHeight = this.displayHeight * this.downsampleRatio; this._resultsToDisplayRatio = this.sampleWidth / this.displayWidth; this.sampleMatRect = new Rectangle(0, 0, this.sampleWidth, this.sampleHeight); this.loadContent(contentPath); } /** * update the BitmapData source used for analysis. */ public function update () :void { this.displayBmpData.draw(this.loader, this.displayMatrix); this.sampleBmpData.fillRect(this.sampleMatRect, 0xFFFFFFFF); this.sampleBmpData.draw(this.loader, this.sampleMatrix); } /** * retrieve the BitmapData source used for analysis. * NOTE: returns the actual BitmapData object, not a clone. */ public function get source () :BitmapData { return this.sampleBmpData; } /** * size of BitmapData source used for analysis. */ public function get sourceSize () :Rectangle { return new Rectangle(0, 0, this.sampleWidth, this.sampleHeight); } /** * ratio of area of reported results to display size. * used to scale results of FLARToolkit analysis to correctly fit display area. */ public function get resultsToDisplayRatio () :Number { return this._resultsToDisplayRatio; } /** * FLARLoaderSource cannot be mirrored; * method is here only for compliance with IFLARSource. */ public function get mirrored () :Boolean { return false; } public function set mirrored (val:Boolean) :void {} private function loadContent (path:String) :void { this.loader = new Loader(); this.loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.onLoadError, false, 0, true); this.loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onLoadError, false, 0, true); this.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onLoaded, false, 0, true); this.loader.load(new URLRequest(path)); } private function onLoadError (evt:Event) :void { var errorText:String = "FLARLoaderSource load error."; if (evt is IOErrorEvent) { errorText = IOErrorEvent(evt).text; } else if (evt is SecurityErrorEvent) { errorText = SecurityErrorEvent(evt).text; } this.onLoaded(evt, new Error(errorText)); } private function onLoaded (evt:Event, error:Error=null) :void { var loaderInfo:LoaderInfo = evt.target as LoaderInfo; loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, this.onLoadError); loaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onLoadError); loaderInfo.removeEventListener(Event.COMPLETE, this.onLoaded); if (error) { throw error; } // BitmapData downsampled from source video, sent to FLARToolkit every frame this.sampleBmpData = new BitmapData(this.sampleWidth, this.sampleHeight, false, 0); this.sampleBitmap = new Bitmap(this.sampleBmpData); this.sampleBitmap.width = this.displayWidth; this.sampleBitmap.height = this.displayHeight; // cropped, full-res video displayed on-screen this.displayBmpData = new BitmapData(this.displayWidth, this.displayHeight, false, 0); this.displayBitmap = new Bitmap(this.displayBmpData); // full-res Bitmap for display this.addChild(this.displayBitmap); // uncomment to view downsampled BitmapData sent to FLARToolkit // this.addChild(this.sampleBitmap); this.buildSampleMatrices(); this.dispatchEvent(new Event(Event.INIT)); } private function buildSampleMatrices () :void { // construct transformation matrix used when updating displayed video // and when updating BitmapData source for FLARToolkit this.displayMatrix = new Matrix(1, 0, 0, 1); this.sampleMatrix = new Matrix( this._resultsToDisplayRatio, 0, 0, this._resultsToDisplayRatio); } } }