使用 Flex Mobile 4.6 在 iOS 上上传图库或捕获的图像
有谁有使用 iOS Flex 4.6 中的相机 API 的经验吗?我遇到了很多设置问题并且缺少文档。我正在尝试设置一个图像上传组件,用户可以在其中捕获新照片或从其库中选择现有照片。
对于捕获来说,当图像保存为 JPEG 时,并且我正在使用 Alchemy swc,似乎会出现巨大的挂起(例如应用程序无响应的 10 秒)。
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 为 true,我可以附加一个加载程序侦听器,但只返回 contentLoaderInfo,它没有引用实际的 File 或 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.
}}
任何帮助将不胜感激。
谢谢!
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.
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);
}
}
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.
}}
Any help would be appreciated.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想我找到了适合我的案例的解决方案,所以我想分享它,以防它可以帮助别人。肖恩胡赛因的帖子绝对让我朝着正确的方向前进。我能够避免同时使用 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:
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.