使用 Flex Mobile 4.6 在 iOS 上上传库或捕获的图像 [英] Upload Library or captured images on iOS with Flex Mobile 4.6

查看:18
本文介绍了使用 Flex Mobile 4.6 在 iOS 上上传库或捕获的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人对 Flex 4.6 和 iOS 中的相机 API 有任何经验?我遇到了很多设置问题并且缺少文档.我正在尝试设置一个图像上传组件,用户可以在其中捕获新照片或从他们的库中选择现有照片.

Does anyone have any experience with the Camera APIs in Flex 4.6 with iOS? I'm running into a lot of setup issues and the documentation is lacking. I'm trying to setup an image upload component where a user can either capture a new photo or choose an existing from their library.

对于捕获,当图像被保存为 JPEG 时,似乎有一个巨大的挂起(比如 10 秒,应用程序没有响应),而我正在使用 Alchemy swc.

For capturing, there seems to be a huge hang (like 10 seconds where the app just sits non-responsive) when the image is being saved as a JPEG, and I'm using the 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 是真的,我可以附加一个加载器侦听器,但它只返回 contentLoaderInfo,它没有对实际文件或 FileRefernce 的引用,所以我不能在不创建临时图像的情况下调用上传方法,这看起来很昂贵并且疯了.

For choosing from the library, I can't get a file reference to actually start the upload. When the select is made, the mediaPromise.file value is null. mediaPromise.isAsync is true and I can attach a loader listener but that only returns the contentLoaderInfo, which has no reference to the actual File or a FileRefernce, so I can't call the upload method without creating a temp image, which seems expensive and crazy.

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.
            }}

任何帮助将不胜感激.

谢谢!

推荐答案

我想我找到了适合我的案例的解决方案,所以我想分享它,以防它可以帮助别人.shaunhusain 的帖子绝对让我朝着正确的方向前进.我能够避免同时使用 Alchemy swc,这在应用程序中节省了大量时间.关键是我发现的这个 AS3 库,它以模仿标准文件上传 POST 操作的方式格式化 URLRequest.这是基本轮廓:

I think I found a solution for works for my case so I wanted to share it in case it can help someone out. shaunhusain's post definitely got me moving in the right direction. I was able to avoid using the Alchemy swc all together which saves a TON of time in the app. The key is this AS3 library I found that formats a URLRequest in a way that mimics a standard file upload POST operation. Here's the basic outline:

我有一个名为状态"的小组件,它是一个带有用户图标和状态文本的覆盖层.当用户想要添加照片时,他们会获得一个 ViewMenu,其中包含从他们的库中获取照片或拍摄新照片的选项.代码的内容如下.

I have a small component called 'status' thats an overlay with an icon and status text for the user. When a user wants to add a photo, they get a ViewMenu with the choices to get the photo from their library or take a new photo. The meat of the code is below.

 //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);
        }

这篇关于使用 Flex Mobile 4.6 在 iOS 上上传库或捕获的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆