/ Published in: ActionScript 3
URL: http://blog.flexnroses.com/?p=95
Expand |
Embed | Plain Text
<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Get That Image" creationComplete="creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import com.flexnroses.mobile.utils.hardware.ExifUtils; import jp.shichiseki.exif.ExifInfo; import jp.shichiseki.exif.ExifLoader; import mx.events.FlexEvent; private var loader:Loader; private var cameraRoll:CameraRoll; private var exifLoader:ExifLoader; private var mediaPromise:MediaPromise; protected function btnLoad_clickHandler(event:MouseEvent):void { cameraRoll.browseForImage(); } //1. instantiate CameraRoll and get its event handlers ready protected function creationCompleteHandler(event:FlexEvent):void { if( CameraRoll.supportsBrowseForImage ) { loader = new Loader(); loader.contentLoaderInfo.addEventListener( Event.COMPLETE, this.contentLoadedHandler ); cameraRoll = new CameraRoll(); cameraRoll.addEventListener( MediaEvent.SELECT, this.mediaSelectHandler ); cameraRoll.addEventListener( Event.CANCEL, errorHandler ); } else { lbl.text = "Unable to access Camera Roll"; } } //2. once CameraRoll is browsed and an image selected, find its Exif data private function mediaSelectHandler( event:MediaEvent ):void { mediaPromise = event.data; lbl.text = mediaPromise.file.url; this.exifLoader = new ExifLoader(); this.exifLoader.addEventListener(Event.COMPLETE, completeHandler ); this.exifLoader.load( new URLRequest( mediaPromise.file.url ) ); } private function errorHandler( event:Event ):void { } //3. once Exif data is available, use loader to obviously load mediaPromised found in step 2 private function completeHandler( event:Event ):void { loader.unload(); loader.loadFilePromise( mediaPromise ); } //4. use exif data and access ExifUtils to get the image found appear eye oriented. private function contentLoadedHandler( event:Event ):void { var exif:ExifInfo = this.exifLoader.exif; var rotation:int = ExifUtils.getEyeOrientedAngle( exif.ifds ); //i created a new bitmap, but otherwise, you could also make use of the line above and //distor the image in your own way. var bitmap:Bitmap = ExifUtils.getEyeOrientedBitmap( Bitmap( event.currentTarget.content ), exif.ifds ); this.image.source = bitmap; } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <s:layout> <s:VerticalLayout gap="10" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"/> </s:layout> <s:Label id="lbl" text="select an image" /> <s:Image id="image" width="100%" height="100%" /> <s:HGroup id="ftr" width="100%"> <s:Button id="btnLoad" label="Load" width="100%" click="btnLoad_clickHandler(event)" /> </s:HGroup> </s:View> ///// package com.flexnroses.mobile.utils.hardware { import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Matrix; import jp.shichiseki.exif.IFDSet; public class ExifUtils { public static const PORTRAIT:int = 6; public static const PORTRAIT_REVERSE:int = 8; public static const LANDSCAPE:int = 1; public static const LANDSCAPE_REVERSE:int = 3; /** * function figures out the rotation needed so the image * appears in the right view for the user * * * @param ifd attribute in exif belonging to image * @return the angle to rotate an image based on ifd information * @see http://bit.ly/j70E7T */ public static function getEyeOrientedAngle( set:IFDSet ):int { var angle:int = 0; if( set.primary[ "Orientation" ] ) { switch( set.primary[ "Orientation" ] ) { case LANDSCAPE: angle = 0; break; case LANDSCAPE_REVERSE: angle = 180; break; case PORTRAIT: angle = 90; break; case PORTRAIT_REVERSE: angle = -90; break; } } return angle; } /** * creates a bitmap appealing to the eye, so that based on provided original bitmap and its IFDSet * it's possible to track the orientation and create a transformed bitmap copied from the original. * * @see <a href="http://www.psyked.co.uk/actionscript/rotating-bitmapdata.htm">rotating-bitmapdata.htm</a> * @see <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/geom/Matrix.html">matrix documentation</a> * * @param bitmap retrieved after selecting an image from CameraRoll * @param set retrieved after loading the Exif data from selected image * @return a new bitmap in the right angle and same dimensions as the original. * */ public static function getEyeOrientedBitmap( bitmap:Bitmap, set:IFDSet ):Bitmap { var m:Matrix = new Matrix(); var orientation:int= set.primary[ "Orientation" ]; var bitmapData:BitmapData; if( orientation == LANDSCAPE || orientation == LANDSCAPE_REVERSE ) { bitmapData = new BitmapData( bitmap.width, bitmap.height, true ); } else { bitmapData = new BitmapData( bitmap.height, bitmap.width, true ); } m.rotate( getEyeOrientedAngle( set ) * ( Math.PI / 180 ) ); if( orientation == PORTRAIT_REVERSE ) { m.translate( 0, bitmap.width ); } else if( orientation == PORTRAIT ) { m.translate( bitmap.height, 0 ); } else if( orientation == LANDSCAPE_REVERSE ) { m.translate( bitmap.width, bitmap.height ); } bitmapData.draw( bitmap, m ); return new Bitmap( bitmapData ); } } }
You need to login to post a comment.
