2012-01-18 1 views
2

Есть ли у кого-нибудь опыт работы с API-интерфейсом камеры в Flex 4.6 с iOS? У меня много проблем с настройкой, и документации нет. Я пытаюсь настроить компонент загрузки изображения, где пользователь может либо захватить новую фотографию, либо выбрать существующую из своей библиотеки.Загрузить библиотеку или снятые изображения на iOS с помощью Flex Mobile 4.6

Для захвата, кажется, что существует огромная зависания (например, 10 секунд, когда приложение просто сидит не реагирует), когда изображение сохраняется в виде JPEG, и я использую swc Alchemy.

 private var cam:CameraUI; 
     protected function takePhotoHandler(event:MouseEvent):void 
     { 
      if(CameraUI.isSupported) { 
       cam = new CameraUI(); 
       cam.addEventListener(MediaEvent.COMPLETE, mediaEventComplete); 
       cam.launch(MediaType.IMAGE); 
      } 
     } 
     protected function mediaEventComplete(e:MediaEvent):void 
     { 
      cam.removeEventListener(MediaEvent.COMPLETE, mediaEventComplete); 
      status.text = "Media captured..." ; 

      var imagePromise:MediaPromise = e.data; 
      var loader:Loader = new Loader(); 
      if(imagePromise.isAsync) { 
       status.text = "Asynchronous media promise." ; 
       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, asyncImageLoadHandler); 
       loader.addEventListener(IOErrorEvent.IO_ERROR, asyncImageErrorHandler); 

       loader.loadFilePromise(imagePromise); 

      } else { 
       status.text = "Synchronous media promise."; 
       loader.loadFilePromise(imagePromise); 
       img.source = loader.content; 
       saveImage(loader.contentLoaderInfo); 
      } 

     } 
     protected function asyncImageLoadHandler(e:Event):void 
     { 
      status.text = "Media loaded in memory."; 
      img.source = e.currentTarget.loader.content; 
      saveImage(e.currentTarget.loader.contentLoaderInfo); 
     } 
     protected function saveImage(loaderInfo:LoaderInfo):void 
     { 
      if(CameraRoll.supportsAddBitmapData){ 
       var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height); 
       bitmapData.draw(loaderInfo.loader); 
       d_trace("bitmapDraw"); 
       //var c:CameraRoll = new CameraRoll(); 
       //c.addBitmapData(bitmapData); 
       d_trace("writing to disk"); 
       var f:File = File.applicationStorageDirectory.resolvePath("temp");  
       var stream:FileStream = new FileStream() 
       stream.open(f, FileMode.WRITE);  
       d_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);  
       d_trace("encoding end"); 
       stream.writeBytes(bytes,0,bytes.bytesAvailable); 
       stream.close(); 
       d_trace(f.url); 
       img.source = f.url; 
       d_trace("UPLOADING START"); 

       f.addEventListener(Event.COMPLETE,uploadCompleteHandler); 
       f.addEventListener(Event.OPEN,openUploadHandler); 
       f.upload(urlRequest); 


      } 
     } 

Для выбора из библиотеки я не могу получить ссылку на файл, чтобы начать загрузку. Когда выбор сделан, значение mediaPromise.file равно null. mediaPromise.isAsync истинно, и я могу подключить слушателя загрузчика, но он возвращает только ContentLoaderInfo, который не имеет ссылки на фактический файл или файл, поэтому я не могу вызвать метод загрузки без создания временного изображения, которое кажется дорогим и псих.

protected function chooseImage(): void { 
    if(CameraRoll.supportsBrowseForImage) { 
     var roll: CameraRoll = newCameraRoll(); 
     roll.addEventListener(MediaEvent.SELECT, roll_selectHandler); 
     var options:CameraRollBrowseOptions = new CameraRollBrowseOptions(); 
     roll.browseForImage(options); 
}} 
     private function roll_selectHandler(event: MediaEvent): void 
     { 

      var imagePromise:MediaPromise = event.data; 

      if(imagePromise.isAsync) { 
       // Here's where I get. Not sure how to get the reference to the file I just selected. 
      }} 

Любая помощь будет оценена по достоинству.

Спасибо!

+1

Вы используете много слов, которые я не знаю, и я профессиональный разработчик Flex ... поздравления :). http://www.adobe.com/devnet/air/articles/uploading-images-media-promise.html Я не пробовал это, но похоже, что вы можете получить IDataInput, который затем вы можете прочитать байты? Вы видели этот пример, это помогает? – shaunhusain

+0

Ничего себе, это именно то, что я искал. Огромное спасибо! Я искал страницы/видеоролики Devnet, предполагая, что кто-то должен был прогнать это уже и никогда не видел этого. – ChickensDontClap

ответ

5

Я думаю, что нашел решение для работы для своего дела, поэтому хотел поделиться им, если он может помочь кому-то. Сообщение shaunhusain определенно заставило меня двигаться в правильном направлении. Мне удалось избежать совместного использования Alchemy, что экономит TON времени в приложении. Ключом является эта библиотека AS3, которую я нашел, которая форматирует URLRequest таким образом, который имитирует стандартную загрузку POST. Вот основной контур:

У меня есть небольшой компонент, называемый статусом, который представляет собой оверлей с иконкой и статусом для пользователя. Когда пользователь хочет добавить фотографию, они получают ViewMenu с выбором, чтобы получить фотографию из своей библиотеки или сделать новую фотографию. Мясо кода ниже.

//IMAGE HANDLING 

//Helpful Links: 
//http://www.quietless.com/kitchen/dynamically-create-an-image-in-flash-and-save-it-to-the-desktop-or-server/ 
//http://stackoverflow.com/questions/597947/how-can-i-send-a-bytearray-from-flash-and-some-form-data-to-php 
// GET WRAPPER CLASS Here: http://code.google.com/p/asfeedback/source/browse/trunk/com/marston/utils/URLRequestWrapper.as 


//This part is basically all based on http://www.adobe.com/devnet/air/articles/uploading-images-media-promise.html 


    protected var cameraRoll:CameraRoll = new CameraRoll(); 

    //User choose to pick a photo from their library 
    protected function chooseImage():void { 
    if(CameraRoll.supportsBrowseForImage) 
    { 
     cameraRoll.addEventListener(MediaEvent.SELECT, imageSelected); 
     cameraRoll.addEventListener(Event.CANCEL, browseCanceled); 
     cameraRoll.addEventListener(ErrorEvent.ERROR, mediaError); 
     cameraRoll.browseForImage(); 
    } else { 
       trace("Image browsing is not supported on this device."); 
    } 
    } 

    //User choose to take a new photo! 
protected var cameraUI:CameraUI = new CameraUI(); 
protected function captureImage():void 
{ 
    if(CameraUI.isSupported) 
    { 
     trace("Initializing..."); 
      cameraUI.addEventListener(MediaEvent.COMPLETE, imageSelected); 
     cameraUI.addEventListener(Event.CANCEL, browseCanceled); 
     cameraUI.addEventListener(ErrorEvent.ERROR, mediaError); 
     cameraUI.launch(MediaType.IMAGE); 
    } else { 
     trace("CameraUI is not supported."); 
    } 
} 


private function browseCanceled (e:Event):void 
{ 
    trace ("Camera Operation Cancelled"); 
} 

private function mediaError (e:ErrorEvent):void 
{ 
    trace ("mediaError"); 
} 


private var dataSource:IDataInput; 
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); 
      upload(imageBytes); 
     } 

     //OK Here's where it gets sent. Once the IDataInput has read the bytes of the image, we can send it via our custom URLRequestWrapper 
        //which will format the request so the server interprets it was a normal file upload. Your params will get encoded as well 
        //I used Uploadify this time but I've used this Wrapper class in other projects with success 
     protected function upload(ba:ByteArray, fileName:String = null):void 
     { 
      if(fileName == null) //Make a name with correct file type 
      {     
       var now:Date = new Date(); 
       fileName = "IMG" + now.fullYear + now.month +now.day + 
        now.hours + now.minutes + now.seconds + ".jpg"; 
      } 

      var loader:URLLoader = new URLLoader(); 
      loader.dataFormat= URLLoaderDataFormat.BINARY; 

      var params:Object = {}; 
      params.name = fileName; 
      params.user_id = model.user.user_id; 

      var wrapper:URLRequestWrapper = new URLRequestWrapper(ba, fileName, null, params); 
      wrapper.url = "http://www.your-domain.com/uploadify.php"; 

      loader.addEventListener(Event.COMPLETE, onUploadComplete); 
      loader.addEventListener(IOErrorEvent.IO_ERROR, onUploadError); 
      loader.load(wrapper.request);   
     } 

     private function onUploadComplete(e:Event):void 
     { 
      trace("UPLOAD COMPLETE"); 
      var bytes:ByteArray = e.currentTarget.data as ByteArray; 
          //Most likely you'd want a server response. It will be returned as a ByteArray, so you can get back to the string: 
      trace("RESPONSE", bytes.toString()); 
     } 

     private function onUploadError(e:IOErrorEvent):void 
     { 
      trace("IOERROR", e.text); 
     } 

 Смежные вопросы

  • Нет связанных вопросов^_^