Avg. Rating 5.0
Tags:



Problem

The CameraRoll class will allow you to add picture taken with CameraUI to the CameraRoll (Photos) gallery on iOS. However the file is still inaccessible due to iOS security and the native JPEGEncoder is very slow.

Solution

You will need to use the Loader, File, FileStream, and Alchemy version of encoding classes to write the new image to a place on the disk you are allowed to access it from.

Detailed explanation

The example below extends this recipe and adds in functionality to write the newly created image to some place on the disk where it is available to you to upload to a server if necessary. This example is much faster as it is using an Alchemy based encoder.

Within the loaderComplete method, a File object is created with a path resolved to the applicationStorageDirectory. Next a FileStream is created and opened in WRITE mode. I then use the Alchemy encoder to encode the jpeg and then write the image to disk using the FileStream and finally show the image by setting the source of the Image component to the file's url. Note, you will need the as3_jpeg_wrapper.swc to run this example.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  applicationComplete="application1_applicationCompleteHandler(event)">

<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<fx:Script>
<![CDATA[
import mx.events.FlexEvent;

private var camera:CameraUI;
private var loader:Loader;

import cmodule.as3_jpeg_wrapper.CLibInit;

private var as3_jpeg_wrapper: Object;

protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
if(CameraUI.isSupported){
camera = new CameraUI();
camera.addEventListener(MediaEvent.COMPLETE, mediaEventComplete);
var loader:CLibInit = new CLibInit;
as3_jpeg_wrapper = loader.init();
}

}

private function mediaEventComplete(event:MediaEvent):void{
var mediaPromise:MediaPromise = event.data;
if(mediaPromise.file == null){
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleted);
loader.loadFilePromise(mediaPromise);
return;
}    
}

private function loaderCompleted(e:Event):void{
var loaderInfo:LoaderInfo = e.target as LoaderInfo;
if(CameraRoll.supportsAddBitmapData){
var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height);
bitmapData.draw(loaderInfo.loader);  
trace("bitmapDraw");
//var c:CameraRoll = new CameraRoll();
//c.addBitmapData(bitmapData);
trace("writing to disk");
var f:File = File.applicationStorageDirectory.resolvePath("temp");     
var stream:FileStream = new FileStream()
stream.open(f, FileMode.WRITE);      
trace("encoding start");
var baSource: ByteArray = bitmapData.clone().getPixels( new Rectangle( 0, 0, loaderInfo.width, loaderInfo.height) );
var bytes: ByteArray = as3_jpeg_wrapper.write_jpeg_file(baSource, loaderInfo.width, loaderInfo.height, 3, 2, 80);     
trace("encoding end");
stream.writeBytes(bytes,0,bytes.bytesAvailable);
stream.close(); 
trace(f.url);
img.source = f.url;
}
}

protected function snapPic_clickHandler(event:MouseEvent):void{
camera.launch(MediaType.IMAGE);
}

]]>
</fx:Script>

<s:Button id="snapPic" top="10" label="Take a Picture" click="snapPic_clickHandler(event)"
  horizontalCenter="0"/>
<s:Image id="img" left="10" right="10" top="70" bottom="10"/>



</s:Application>

+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes