2

我使用 Jason Sturges 提供的 DevGirl XpenseIt 解决方案取得了很大的成功,以响应其他几个寻求帮助的请求:(http://stackoverflow.com/questions/11812807/take-photo-using- adobe-builder-flex-for-ios 是最好的例子)

取得了巨大的成功,除了在使用 CameraUI 和教程中的 util 类拍摄照片后按下 iOS6 中的“使用”按钮之间,它需要 47 只 1-河马,2 只河马,直到“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
4

2 回答 2

1

我能够通过从流程中删除一个步骤来解决我的延迟问题。这一步是我自己(目前)不需要但其他人可能需要的一步,因此删除它并不能真正回答“为什么这个看似合理的过程要花费看似不合理的时间”的问题。

我需要 BitmapData,而不是外部文件,而不是:

Camera => [snap] => Media Promise => Loader => Write File => Event => Read File => Use BitmapData

我重写了类以删除 File/AppStorage i/o。

Camera => [snap] => Media Promise => Loader => 使用 BitmapData

所以非常合理(和预期的补偿时间)。

然而,我仍然感到惊讶的是,使用 CameraUtil 类中使用的方法将数据写入文件需要这么长时间。我确实需要将这些图像写到文件中,但直到用户将大小减小到 1024x768 裁剪区域并将它们编码为非常压缩的 jpg,所以希望我只会与一小部分挂起/补偿时间。

有人知道...从 Adob​​e AIR(通过 flex)将 1 个文件写入 iOS 中的应用程序存储需要很长时间吗?

于 2012-12-07T15:10:47.350 回答
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 进行编码。但与此同时... ;)

于 2013-01-28T09:38:17.380 回答