Adobe
产品
Acrobat
Creative Cloud
创意套装
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
更多产品
解决方案
数字营销
数字媒体
教育
金融服务业
政府部门
网页体验管理
更多解决方案
学习帮助下载公司
商店
在线商店
批量许可
查找经销商
搜索
 
信息 登录
欢迎,我的支持
我的帐户
注销
为何登录?登录后可以管理您的帐户,访问试用版下载、产品扩展和社区区域等。
Adobe
产品 分类 购买   搜索  
解決方案 公司
学习
登录 注销 我的货物 我的支持
Date Date
Qty:
Subtotal
Checkout
Adobe 开发者中心 / Adobe AIR 开发人员中心 /

实现AIR调用iOS照片库的短教程

作者 James Li

James Li
  • Adobe

创建日期

20 November 2011

页面工具

在 Facebook 上共享
在 Twitter 上共享
在 LinkedIn 上共享
书签
打印

Tags

刚刚用了12个小时的时间解决了这个问题,趁热打铁给大家分享一下。

本文的目的如题,介绍一下如何用ANE实现在AIR中打开iOS照片库中的图片。请注意阅读本文之前先了解ANE的基本概念,以及Flash开发iOS应用的基本流程,在我博客中的前文已经多次提起,这里不再重复。本文只对核心内容做介绍。

除了本文介绍的方法之外,也许还有更好的解决方案,欢迎各位高手补充和纠正。

下面我就单刀直入直接介绍代码和思路。
首先在OBJC里使用UIImagePicker浏览照片库:

//创建mediaUI,这是一个UIViewController的子类,用来显示Native的照片浏览窗口 UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init]; mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; mediaUI.allowsEditing = NO; //指定UIImagePickerDelegate的接口,observer是我自定义的类,使用Delegate回调接口是OBJC的一种典型的事件回调机制。 mediaUI.delegate = observer; //在AIR应用上加UIViewController showModalViewController(mediaUI);

这就是如何在AIR上增加和移除原生独占窗口的例子:

void showModalViewController(UIViewController* viewController){ if(currentModalViewController!=nil){ dismissModalViewController(currentModalViewController); } //使用Singleton对象sharedApplication的keyWindow属性可以获取AIR应用的主窗口。 UIWindow *window = [[UIApplication sharedApplication] keyWindow]; //为即将显示的独占窗口创建一个父级UIViewController UIViewController *parentViewController = [[UIViewController alloc] init]; //在主窗口加上这个父级controller,由于Native的view大多是用UIViewController构建的, //而AIR应用的基础并没有建立在UIViewController之上,所以需要用这种方式来做桥接。 //这个概念类似于用UIComponent连接MXML Display组件和AS DisplayObject。 [window addSubview:parentViewController.view]; //显示独占窗口 [parentViewController presentModalViewController:viewController animated:YES]; currentModalViewController = viewController; } void dismissModalViewController(UIViewController* viewController){ if(viewController !=nil){ UIViewController *parentViewController = [viewController parentViewController]; [parentViewController dismissModalViewControllerAnimated:NO]; [parentViewController.view removeFromSuperview]; currentModalViewController = nil; } }

接下来一步是等待用户选择图片,对于程序来说,是等待调用UIImagePickerDelegated的方法didFinishPickingImage,
现在我们就开始介绍整个思路的核心。

ANE的核心在于FlashRuntimeExtension API,这里面包括了一些关键的方法和数据结构。详见这里http://help.adobe.com/zh_CN/air/extensions/WSb464b1207c184b14-62b8e11f12937b86be4-8000.html。虽然通过这套API可以实现两者之间的通信,但是通信的地位是不同的。除了基础数据类型,ActionScript的 BitmapData,ByteArray也能够以形参的方式直接传递到C,但是C传给ActionScript的数据只有基础类型,位图是传递不了的。但是FRE给我们提供了一个比较有趣的方案,可以将AS位图对象直接交给C来处理,通过内存地址直接修改,不需要回传。

基于这个思路,下一步要做的就是先把照片库中的照片拿出来,把照片尺寸传给Flash,让Flash创建一个等大的空位图并且传回来,最后用Objective-C修改这个位图。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo { //标记所选择的图片 self.selectedImage = image; //取得图片的尺寸并保存在一个XML中 CGSize image_size = image.size; NSMutableString *retXML = [NSMutableString stringWithFormat:@"<image>"]; [retXML appendFormat:@"<width>%i</width>",(int)image_size.width]; [retXML appendFormat:@"<height>%i</height>",(int)image_size.height]; [retXML appendFormat:@"</image>"]; //通过StatusEvent将图片尺寸派发给Flash FREDispatchStatusEventAsync(g_ctx, (const uint8_t*)"selectedImageReady", (const uint8_t*)[retXML UTF8String]); //关掉选取图片的独占窗口 dismissModalViewController(picker); }

在ActionScript里,用我们熟悉的方式创建一个BitmapData,然后传给C

private function onStatus(e:StatusEvent):void{ switch(e.code){ case "selectedImageReady": var xml:XMLList = new XMLList(e.level); var imageWidth:Number = Number(xml.width); var imageHeight:Number = Number(xml.height); var bitmapData:BitmapData = new BitmapData(imageWidth,imageHeight,true,0x00); dispatchEvent(new ExtensionEvent(ExtensionEvent.GET_BITMAPDATA, [drawAsSelectedImage(bitmapData)])); break; } } //调用C的函数,把BitmapData对象移交出去。 public function drawAsSelectedImage(bitmapData:BitmapData):BitmapData{ ctx.call("getSelectedImage",bitmapData); return bitmapData; }

最后就是在C里处理这张图片,代码注释里是详细介绍。

FREObject getSelectedImage(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { //创建一个FREBitmapData对象bitmapData,这个对象是ActionScript中BitmapData的代表,共享一个内存地址。 FREBitmapData bitmapData; //从参数组argv中拿出AS的BitmapData对象,用FREAcquireBitmapData方法将bitmapData指针指向这个BitmapData对象。 //这样,只要改动bitmapData的位图信息,就会直接影响 AS里面创建的BitmapData对象。 FREResult re = FREAcquireBitmapData(argv[0], &bitmapData); //找到刚才从照片库中选择并保存的那张图片 UIImage *image = observer.selectedImage; //取出尺寸 CGSize image_size = image.size; //用Core Graphic API的CGBitmapContextCreate方法,在bitmapData的指针位置创建一个位图绘制环境。 CGContextRef context = CGBitmapContextCreate(bitmapData.bits32, image_size.width, image_size.height, 8, 4 * image_size.width, CGColorSpaceCreateDeviceRGB(), CGImageGetBitmapInfo([image CGImage])); //创建一个位图绘制区域 CGRect rect = {{0,0},{image_size.width,image_size.height}}; //绘制位图 CGContextDrawImage(context, rect, [image CGImage]); //位图绘制完成后,必须调用FREInvalidateBitmapDataRect方法来重绘位图的修改区域。 FREInvalidateBitmapDataRect(argv[0], 0, 0, (int)image_size.width, (int)image_size.height); //最后把BitmapData交回给Flash,结束修改动作。这个时候ActionScript里的这个BitmapData对象就已经被绘制成了照片库中选择的那张图片。 FREReleaseBitmapData(argv[0]); //释放内存 CGContextRelease(context); return nil; };

补充一点:
从OBJC获取的照片是BGR图片,在AS中使用之前需要转换成RGB:

public static function convertRGB2BGR(bitmapData:BitmapData):BitmapData{ var outputBitmapData:BitmapData = new BitmapData(bitmapData.width,bitmapData.height,true); outputBitmapData.copyChannel(bitmapData,bitmapData.rect,new Point(),BitmapDataChannel.BLUE, BitmapDataChannel.RED); outputBitmapData.copyChannel(bitmapData,bitmapData.rect,new Point(),BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); outputBitmapData.copyChannel(bitmapData,bitmapData.rect,new Point(),BitmapDataChannel.RED, BitmapDataChannel.BLUE); return outputBitmapData; }

More Like This

  • 从CameraRoll和CameraUI上传图像
  • 开发Adobe AIR的原生扩展
  • Packaging Adobe AIR applications for the desktop
  • Using Flash Builder 4.5 to package applications for Apple iOS devices
  • Adobe AIR 3新特性
  • Adobe AIR 3的安装与部署选项
  • Licensing Adobe AIR applications on Android
  • Packaging Adobe AIR applications
  • 使用Flash Builder 4.5 对 Apple iOS设备的应用程序进行打包
  • 使用Flash Builder 4.5 对 Google Android 设备的应用程序进行打包

Tutorials and samples

Tutorials

  • Using the In-App Billing Adobe AIR native extension for Android
  • Using the iOS In-App Purchase native extension for Adobe AIR
  • Using the GoViral social networking extension for iOS
  • Developing native extensions for Adobe AIR

Samples

  • Licensing Adobe AIR applications on Android
  • Using web fonts with Adobe AIR 2.5
  • Using Badger for Adobe AIR applications

AIR blogs

More
05/15/2012 What’s New in Flash Player 11.2 and Adobe AIR 3.2 Slides and...
05/14/2012 Adobe Flash Platform Runtime and SDK Archives
05/14/2012 Monster’s Socks on the iPad with Adobe AIR
05/10/2012 What’s New in Flash Player 11.2 and Adobe AIR 3.2

AIR Cookbooks

More
02/09/2012 Using Camera with a MediaContainer instead of VideoDisplay
01/20/2012 Skinnable Transform Tool
01/18/2012 Recording webcam video & audio in a flv file on local drive
12/12/2011 Date calculations using 'out-of-the-box' functions

产品

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • 移动应用程序
  • Photoshop
  • Touch Apps

解决方案

  • 数字营销
  • 数字媒体
  • 网页体验管理

行业

  • 教育
  • 金融服务业
  • 政府部门

帮助

  • 产品帮助中心
  • 订货和退货
  • 下载和安装
  • 我的 Adobe

学习

  • Adobe 开发人员连接
  • Adobe TV
  • 培训和认证
  • 论坛
  • 设计中心

购买方式

  • 在线商店
  • 批量许可
  • 查找经销商

下载

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

公司

  • 新闻编辑室
  • 合作伙伴计划
  • 公司社会责任
  • 工作机会
  • 投资者关系
  • 事件
  • 法律
  • 安全
  • 联系 Adobe
选择您的地区 中国(更改)
选择您的地区 关闭

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

使用条款 | 隐私政策和 Cookies (更新)

京 ICP 备 10217899 号 京公网安备 110105010404