最近flex的系统需要一个图片共享的功能,就是一方上传或者使用摄像头拍摄一张图片,聊天的另外一方马上就能看得到。
那么我一想挺简单的,使用共享对象不就解决了,把图片的数据放到共享对象中,对方不就收到了么?谁知中途遇到几个非常棘手的问题,本来一天的工作变成了3天。下面把这几个典型的问题记录下来,希望遇到类似问题的朋友能够得到一些启发。
- NavigatorContent遭遇typeerror 1009
熟悉的朋友都应该知道,这是空指针被引用抛出的错误,但是问题是这个对象是一个flex的组件,应该flex来初始化的,但是flex没有初始化,这就让我很纠结。相关的组件是下面的screenimg:
<s:NavigatorContent width="100%" height="100%" label="屏幕共享及图片显示"
icon="@Embed('../pics/screen.png')">
<s:Image x="0" y="0" width="623" height="542" id="screenimg" />
</s:NavigatorContent>
看上去这没有什么错误,于是我百度、google一起用,终于在http://blog.sina.com.cn/s/blog_604fb7ae0101azkb.html中找到了解决方案,原来flex为了提高效率会进行延迟初始化,在我的这个项目中就是必须点击相关的NavigatorContent 才能初始化这个选项卡中的组件。解决办法就是在application中添加creationPolicy="all"。 - 截屏时遇到securityerror 2123错误。
上面的typeerror也只是多花了一个小时的时间,这个security错误可是多花了我一天多的时间。过程是这样的:项目需要我对整个应用进行截屏,生成图片数据然后发送,但是写完代码之后怎么运行也不对,flex的web项目我也设置了调试,于是使用最笨的办法:二分法,最后定位到的错误是在bitmapdata的draw方法抛出securityerror。花了好几个小时思考之后觉得可能是应用之后有一个视频组件,当截屏遇到视频流的时候,不允许客户端进行读写。但是怎么解决这个问题呢?于是我又开始百度+google,各种中文文章英文文章看过之后,依然无解,一天就这样过去之后,遗憾的入睡了。第二天起来继续搜,看上去应该是application.xml的设置问题,花了好几个小时之后,又在http://blog.csdn.net/kvgnt/article/details/6704313中找到了答案,原来在red5中配置文件已经不是application.xml了,变成了red5-web.xml。这个问题又解决了。 - 怎么截屏?
网上基本上使用bitmapdata.draw方法或者是ImageSnapshot类,后者只有flash 10以上才支持。经过考虑之后选择后者,因为ImageSnapshot直接能够生成png图片数据,并且直接能够拿到byte数组,bitmapdata.draw还要进行大量的数据转换,转为byte数组然后发送,接收方再进行解码。我是一个懒人,选择ImageSnapshot得到byte数组,写到共享对象中。 - 怎么把bytearray数据还原为图片显示出来。
经过我的最佳实践,最好的办法是显示部分使用 <s:Image x="0" y="0" width="623" height="542" id="screenimg" />
加载byte数组使用loader,并且注册loader的commplete事件处理函数,然后在事件处理函数中这样处理:
private function screenLoadCompleterHandler(event:Event):void{ //将加载的图片添加到Sprite容器中, screenimg.source=loader.content; return; }