Загрузите библиотеку или снятые изображения на iOS с помощью Flex Mobile 4.6 - PullRequest
2 голосов
/ 18 января 2012

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

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

        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 равно нулю.mediaPromise.isAsync имеет значение true, и я могу подключить прослушиватель загрузчика, но он возвращает только contentLoaderInfo, который не имеет ссылки на фактический файл или FileRefernce, поэтому я не могу вызвать метод загрузки без создания временного изображения, которое кажется дорогимсумасшедший.

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 Ответ

5 голосов
/ 07 февраля 2012

Я думаю, что нашел решение для работ для своего случая, поэтому я хотел поделиться им, если это может кому-то помочь.Пост Шонхусейна определенно заставил меня двигаться в правильном направлении.Мне удалось избежать совместного использования Alchemy SWC, что экономит ТОННУ времени в приложении.Ключ - это библиотека 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/
///465729/kak-ya-mogu-otpravit-bytearray-iz-flash-i-nekotorye-dannye-formy-v-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);
        }
...