如何在actionscript 3.0中从cameraUI for iOS旋转图像
我正在使用ActionScript构build器中的ActionScript 3.0构build应用程序。 这是这个问题的后续问题,它的作品,但是当我拍照时,图像旋转到左边。 我如何检查用户拿着手机的方式? 然后用什么代码将图像旋转到相应的位置?
先谢谢了!
编辑:我使用这段代码来旋转图像,但它似乎只旋转正在显示的图像不是图像文件,有什么想法?
var mat:Matrix = new Matrix(); mat.translate(-W/2, -H/2); mat.rotate(Math.PI/2); mat.translate(+W/2, +H/2); mat.concat(myObj.transform.matrix); myObj.transform.matrix = mat;
〜MYY
您可以使用Stage.deviceOrientation或Stage.orientation *来确定电话的方向。
*不知道这是否适用于iOS
它是你想旋转的BitmapData结果本身(即创build一个带有旋转图像的新的BitmapData),或者只是旋转显示列表上的位图?
编辑:
好吧,inheritance人旋转BitmapData对象的一些代码:
function rotateBitmapData(angle:int, source:BitmapData):BitmapData { var newWidth:int = source.rect.width; var newHeight:int = source.rect.height; if (angle==90 || angle==270) { newWidth = source.rect.height; newHeight = source.rect.width; } var newBmd:BitmapData = new BitmapData(newWidth, newHeight, source.transparent); var tx:Number = 0; var ty:Number = 0; if (angle==90 || angle==180) { tx = newWidth; } if (angle==180 || angle==270) { ty = newHeight; } var matrix:Matrix = new Matrix(); matrix.createBox(1, 1, Math.PI*angle/180, tx, ty); newBmd.draw(source, matrix); return newBmd; }
angular度应该是0,90,180或270.它将返回一个按指定angular度旋转的新BitmapData对象。
当你的cameraUI视图处于活动状态时,你不能获取stage.orientation
数据,所以我在这里解释了同样的问题,请注意这个控制器有许多可重用的function,我首先从媒体承诺中获取原始图像数据(这个原始数据有EXIF数据,我会阅读从相机获取图像的方向)然后,我把这个byteArray转换为BitmapData,然后调整和规模,因为我需要。 有一件事要注意的是,如果你将原始图像数据转换成位图数据,你将失去EXIF数据,所以在修改图像之前阅读它,希望这有帮助,我发布在这里迟了我知道,但没有其他的解决scheme在networking上也许有人会需要这个时间。 干杯
SnapshotController.as
package controllers { import flash.display.BitmapData; import flash.display.JPEGEncoderOptions; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.events.IEventDispatcher; import flash.events.MediaEvent; import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; import flash.geom.Matrix; import flash.geom.Rectangle; import flash.media.CameraUI; import flash.media.MediaPromise; import flash.media.MediaType; import flash.utils.ByteArray; import flash.utils.IDataInput; import mx.utils.Base64Encoder; import classes.APIupload; public class SnapshotController { private var cameraUI:CameraUI = new CameraUI(); private var dataSource:IDataInput; private var tempDir:File = new File(); private var imageOrientation:int = 0 ; public function SnapshotController() { } public function LaunchCameraUI():void { if( CameraUI.isSupported ) { trace( "Initializing camera..." ); cameraUI.addEventListener( MediaEvent.COMPLETE, imageSelected ); cameraUI.launch( MediaType.IMAGE ); } else { trace( "CameraUI is not supported."); } } private function imageSelected( event:MediaEvent ):void { trace( "Media selected..." ); var imagePromise:MediaPromise = event.data; dataSource = imagePromise.open(); if( imagePromise.isAsync ) { trace( "Asynchronous media promise." ); var eventSource:IEventDispatcher = dataSource as IEventDispatcher; eventSource.addEventListener( Event.COMPLETE, onMediaLoaded ); } else { trace( "Synchronous media promise." ); readMediaData(); } } private function onMediaLoaded( event:Event ):void { trace("Media load complete"); readMediaData(); } private function readMediaData():void { var imageBytes:ByteArray = new ByteArray(); dataSource.readBytes( imageBytes ); imageOrientation = getOrientation(imageBytes); //saveImageFile(imageBytes); //Saving this byteArray will save a big file with the EXIF in it. var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.INIT, onMediaPromiseLoaded); loader.loadBytes(imageBytes); } private function onMediaPromiseLoaded(e:Event):void { trace("Media file loaded"); var base64Enc:Base64Encoder = new Base64Encoder(); var mpLoaderInfo:LoaderInfo = e.target as LoaderInfo; mpLoaderInfo.removeEventListener(Event.COMPLETE, onMediaPromiseLoaded); var scale:Number = 0.25; var matrix:Matrix = new Matrix(); matrix.scale(scale, scale); var jpgQuality:int = 80; var bmd:BitmapData = new BitmapData(mpLoaderInfo.width*scale, mpLoaderInfo.height*scale); bmd.draw(mpLoaderInfo.content,matrix,null,null,null,true); var rotatedBMD:BitmapData = rotateBitmapData(bmd, imageOrientation); var bytes:ByteArray = rotatedBMD.encode(new Rectangle(0,0, rotatedBMD.width , rotatedBMD.height), new JPEGEncoderOptions(jpgQuality), bytes); saveImageFile(bytes); //this is the smaller file saved. it does not have EXIF data but you can write your own using AS3 eXIF class. } private function rotateBitmapData( bitmapData:BitmapData, degree:int = 0 ) :BitmapData { var newBitmap:BitmapData; var matrix:Matrix = new Matrix(); matrix.rotate( degree * (Math.PI / 180) ); if ( degree == 90 ) { newBitmap = new BitmapData( bitmapData.height, bitmapData.width, true ); matrix.translate( bitmapData.height, 0 ); } else if ( degree == -90 || degree == 270) { newBitmap = new BitmapData( bitmapData.height, bitmapData.width, true ); matrix.translate( 0, bitmapData.width ); } else if ( degree == 180 ) { newBitmap = new BitmapData( bitmapData.width, bitmapData.height, true ); matrix.translate( bitmapData.width, bitmapData.height ); }else if(degree == 0){ newBitmap = new BitmapData( bitmapData.width, bitmapData.height, true ); //matrix.translate( bitmapData.width, bitmapData.height ); } newBitmap.draw( bitmapData, matrix, null, null, null, true ) return newBitmap; } private function saveImageFile(ba:ByteArray):void{ var now:Date = new Date(); var filename:String = "IMG" + now.fullYear + now.month + now.day + now.hours + now.minutes + now.seconds + ".jpg"; var temp:File = File.documentsDirectory.resolvePath( filename ); var stream:FileStream = new FileStream(); stream.open( temp, FileMode.WRITE ); stream.writeBytes( ba ); stream.close(); } private function getOrientation(jpeg:ByteArray):int{ if (jpeg == null) { return 0; } var offset:int = 0; var length:int = 0; while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) { var marker:int = jpeg[offset] & 0xFF; // Check if the marker is a padding. if (marker == 0xFF) { continue; } offset++; // Check if the marker is SOI or TEM. if (marker == 0xD8 || marker == 0x01) { continue; } // Check if the marker is EOI or SOS. if (marker == 0xD9 || marker == 0xDA) { break; } // Get the length and check if it is reasonable. length = pack(jpeg, offset, 2, false); if (length < 2 || offset + length > jpeg.length) { trace("Invalid length"); return 0; } // Break if the marker is EXIF in APP1. if (marker == 0xE1 && length >= 8 && pack(jpeg, offset + 2, 4, false) == 0x45786966 && pack(jpeg, offset + 6, 2, false) == 0) { offset += 8; length -= 8; break; } // Skip other markers. offset += length; length = 0; } if (length > 8) { // Identify the byte order. var tag:int = pack(jpeg, offset, 4, false); if (tag != 0x49492A00 && tag != 0x4D4D002A) { trace("Invalid byte order"); return 0; } var littleEndian:Boolean = (tag == 0x49492A00); // Get the offset and check if it is reasonable. var count:int = pack(jpeg, offset + 4, 4, littleEndian) + 2; if (count < 10 || count > length) { trace( "Invalid offset"); return 0; } offset += count; length -= count; // Get the count and go through all the elements. count = pack(jpeg, offset - 2, 2, littleEndian); while (count-- > 0 && length >= 12) { // Get the tag and check if it is orientation. tag = pack(jpeg, offset, 2, littleEndian); if (tag == 0x0112) { // We do not really care about type and count, do we? var orientation:int = pack(jpeg, offset + 8, 2, littleEndian); switch (orientation) { case 1: return 0; case 3: return 180; case 6: return 90; case 8: return 270; } trace( "Unsupported orientation"); return 0; } offset += 12; length -= 12; } } trace( "Orientation not found"); return 0; } private function pack(bytes:ByteArray,offset:int,length:int, littleEndian:Boolean):int { var step:int = 1; if (littleEndian) { offset += length - 1; step = -1; } var value:int = 0; while (length-- > 0) { value = (value << 8) | (bytes[offset] & 0xFF); offset += step; } return value; } } }
您可以使用StageOrientationEvent.ORIENTATION_CHANGING
事件:
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, OrientationChangeHandler); private function OrientationChangeHandler(e:StageOrientationEvent):void { switch (e.afterOrientation) { case StageOrientation.DEFAULT : break; case StageOrientation.ROTATED_RIGHT : break; case StageOrientation.ROTATED_LEFT : break; case StageOrientation.UPSIDE_DOWN : break; } }
这可以帮助你。