我使用Jason Sturges提供的DevGirl XpenseIt解决方案取得了很大的成功,以回应其他几个寻求帮助的请求:(http://stackoverflow.com/questions/11812807/take-photo -using-adobe-builder-flex-for-ios是最好的例子)
除了在使用CameraUI拍摄照片后iOS6中的“使用”按钮与教程中的util类之间按下时,它取得了巨大的成功,它需要完整的47只1只河马,2只hippapotamusses,直到'fileReady'事件发生。
在我看来,似乎不应该让Loader类非常长。
我能做些什么来改善这种表现吗?我不得不添加一个快速等待的UI元素,这样我的用户就不会认为该程序已挂起。以下是我正在使用的上述CameraUtil.as的代码。
// http://stackoverflow.com/questions/11812807/take-photo-using-adobe-builder-flex-for-ios
package classes
{
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.MediaEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.media.CameraRoll;
import flash.media.CameraUI;
import flash.media.MediaPromise;
import flash.media.MediaType;
import flash.utils.ByteArray;
import mx.graphics.codec.JPEGEncoder;
import events.CameraEvent;
[Event(name = "fileReady", type = "events.CameraEvent")]
public class CameraUtil extends EventDispatcher
{
protected var camera:CameraUI;
protected var loader:Loader;
public var file:File;
public function CameraUtil(target:IEventDispatcher=null)
{
super(target);
if (CameraUI.isSupported)
{
camera = new CameraUI();
camera.addEventListener(MediaEvent.COMPLETE, mediaEventComplete);
}
} // End CONSTRUCTOR CameraUtil
public function takePicture():void
{
if (camera)
camera.launch(MediaType.IMAGE);
} // End FUNCTION takePicture
protected function mediaEventComplete(event:MediaEvent):void
{
var mediaPromise:MediaPromise = event.data;
if (mediaPromise.file == null)
{
// For iOS we need to load with a Loader first
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleted);
loader.loadFilePromise(mediaPromise);
return;
}
else
{
// Android we can just dispatch the event that it's complete
file = new File(mediaPromise.file.url);
dispatchEvent(new CameraEvent(CameraEvent.FILE_READY, file));
}
} // End FUNCTION mediaEventComplete
protected function loaderCompleted(event:Event):void
{
var loaderInfo:LoaderInfo = event.target as LoaderInfo;
if (CameraRoll.supportsAddBitmapData)
{
var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height);
bitmapData.draw(loaderInfo.loader);
file = File.applicationStorageDirectory.resolvePath("receipt" + new Date().time + ".jpg");
var stream:FileStream = new FileStream()
stream.open(file, FileMode.WRITE);
var j:JPEGEncoder = new JPEGEncoder();
var bytes:ByteArray = j.encode(bitmapData);
stream.writeBytes(bytes, 0, bytes.bytesAvailable);
stream.close();
dispatchEvent(new CameraEvent(CameraEvent.FILE_READY, file));
}
} // End FUNCTION loaderComplete
} // End CLASS CameraUtil
} // End PACKAGE classes
答案 0 :(得分:1)
我能够通过从流程中删除一个步骤来解决我的延迟问题。这个步骤是我自己不需要的(目前),但其他人可能会这样做,所以删除它并不能解决“为什么这个看似合理的过程需要花费不合理的时间。” p>
我需要BitmapData,而不是外部文件,而不是:
相机=> [snap] =>媒体承诺=> Loader =>写文件=>事件=>阅读文件=>使用BitmapData
我重新编写了类来删除File / AppStorage i / o。
相机=> [snap] =>媒体承诺=> Loader =>使用BitmapData
所以非常合理(和预期的比赛时间)。
然而,我仍然感到惊讶的是,使用CameraUtil类中使用的方法将数据写入文件需要很长时间。我确实需要将这些图像写到文件中,但是直到用户将大小缩小到1024x768裁剪区域并将其编码为非常压缩的jpg,所以希望我只能在较小部分的挂起/比较时间。
任何人都知道......从iOS AIR(通过flex)在iOS中向应用程序存储写入1个文件需要这么长时间吗?
答案 1 :(得分:1)
我发现这个过程也非常缓慢...... 然而,似乎JPEGEncoder对这种延迟做出了很大贡献。 使用可在此处找到的优化编码器,您可以大大加快这一过程。
http://www.bytearray.org/?p=775
根据您的设备,它比原始设备快2到4倍。
可以省略的另一个步骤是bitmapData.draw(),它也很慢,直接使用Loader.content。这样你就可以跳过另一个位图实例的实例化,这会破坏内存的使用。
像这样:
protected function loaderCompleted(event:Event):void
{
var loader:Loader = (event.target as LoaderInfo).loader;
var bitmap:Bitmap = loader.content as Bitmap;
(...)
}
尽管如此,我还在等待有人写一个iOS .ane,它应该可以在几毫秒而不是秒内编码jpg。但在此期间......;)