`

[转] [Flash/Flex] <What can you do with bytes ?> 第二章 第二节: 嵌入式资源

阅读更多
http://bbs.9ria.com/viewthread.php?tid=76876&extra=page%3D1%26amp%3Borderby%3Ddateline%26amp%3Bfilter%3D2592000

嵌入式资源
另一个常用功能就是嵌入外部资源(XML或者Pixel Bender Kernel 滤镜)时会用到.我们经常会碰到的问题就是将那些运行时依赖的资源嵌入到外部swf中.一些服务端拒绝swf拥有外部依赖(external dependency),所以假设你开发了一个小型的应用或游戏并且在几分钟后你需要快速的删除所有外部依赖(external dependency),你可以使用Embed标签来实现这一功能.
在下面的代码中,我们使用Embed标签来嵌入一个外部的 Pixel Bender 滤镜
      
  [Embed(source="myFilter.pbj", mimeType="application/octet-stream")] 
        var myShaderKernel:Class; 

 

在编译时, Pixel Bender 滤镜将被当做一个ByteArray嵌入,注意mimeType application/octet-stream的用途就是允许嵌入资源被当做ByteArray.
更一般的我们也可以将XML作为嵌入资源:
import flash.utils.ByteArray; 

[Embed(source="test.xml", mimeType="application/octet-stream")] 
var xmlStream:Class; 

// instanciate the stream as a ByteArray 
var xmlBytes:ByteArray = new xmlStream(); 

// read the XML String from the byte stream 
var xmlString:String = xmlBytes.readUTFBytes( xmlBytes.bytesAvailable ); 

// instanciate a XML object by passing the content 
var myXML:XML = new XML(xmlString); 

/* 
outputs : 
<menu> 
  <item/> 
  <item/> 
  <item/> 
</menu> 
*/ 
trace ( myXML ); 

// outputs : 3  
trace ( myXML.item.length() ); 


 

任何东西都可以通过这种方法嵌入,我们通过bytearray的API来操作这里嵌入的原始二进制数据 .但需要强调的是上一段代码有一点冗余,所以我们可以通过使用特定的mimeType,来强制的要求转码器将其映射为特定的类型.在下列的代码中,你会看到同样的嵌入使用mimeType后代码变得极其简单.
import flash.utils.ByteArray; 

[Embed(source="test.xml", mimeType="text/xml")] 
var xmlStream:Class; 

// instanciate a XML object by passing the content 
var myXML:XML = new XML (xmlStream.data); 

/* 
outputs : 
<menu> 
  <item/> 
  <item/> 
  <item/> 
</menu> 
*/ 
trace ( myXML ); 

// outputs : 3  
trace ( myXML.item.length() );

 

很便捷吧?接下来让我们来了解一下怎么样在运行时注入和重建bytes的内容.Adobe Flash Player 提供了一个非常强大的API来处理这种情景.

注入bytes

一般来说注入的对象可以是图像,字体,甚至是swf.Flash player 中没有SWF类型,但是你猜怎么着?Loader对象的API中有一个loadBytes.
这就是允许我们将swf当做一个ByteArray注入到Loader对象中并可以运行它:
import flash.utils.ByteArray; 
import flash.display.Loader; 

[Embed(source="test-loading.swf", mimeType="application/octet-stream")] 
var swfStream:Class; 

// instanciate the stream as a ByteArray 
var swfBytes:ByteArray = new swfStream(); 

// instanciate a Loader 
var myLoader:Loader = new Loader(); 

// inject the embedded stream inside the Loader 
// the SWF is executed automatically 
myLoader.loadBytes(swfBytes);
 

 

为了显示它,我们只需要将Loader添加到显示列表即可:
import flash.utils.ByteArray; 
import flash.display.Loader; 

[Embed(source="test-loading.swf", mimeType="application/octet-stream")] 
var swfStream:Class; 

// instanciate the stream as a ByteArray 
var swfBytes:ByteArray = new swfStream(); 

// instanciate a Loader 
var myLoader:Loader = new Loader(); 

// show the Loader object 
addChild ( myLoader ); 

// inject the embedded stream inside the Loader 
// the SWF is executed automatically What can you do with bytes ? – Chapter 2 – Everyday bytes 
myLoader.loadBytes(swfBytes); 

 
复制代码
对于图像或者声音,你甚至不需要设定mimeType.转码器不需要任何干预就可以自动将stream映射成正确的类型.
import flash.utils.ByteArray; 
import flash.display.Bitmap; 

[Embed(source="ferrari-demo.png")] 
var myImageStream:Class; 

// instanciate the image as a classic Bitmap instance 
var myImage:Bitmap = new myImageStream(); 

// show it! 
addChild ( myImage );

 

让我们再深入了解一下图像,在下面的部分我们将会用一种新的方法来动态加载图像.

图像的渐进式加载
Flash player中另一个和byte相关的强大API叫做:URLStream,这个API允许我们在FLash player中下载东西并可以访问已下载的内容.其形式如同一个由服务器推送数据的soket一样.
让我们来看下面的代码:
// creates a URLStream object 
var stream:URLStream = new URLStream(); 


// listen to the ProgressEvent.PROGRESS event to grab the incoming bytes 
stream.addEventListener ( ProgressEvent.PROGRESS, onProgress ); 
stream.addEventListener ( Event.COMPLETE, onComplete ); 

// download the google.com index page 
stream.load ( new URLRequest ("http://www.google.com" ) ); 

function onProgress ( e:ProgressEvent ):void 
{ 
   trace ("progress"); 
} 

function onComplete ( e:Event ):void 
{ 
   trace ("complete"); 
} 


我们可以看到 ProgressEvent.PROGRESS 事件被广播了多次,Event.COMPLETE 事件在结束时被广播了一次.
但是当一些数据被下载后你的确是可以通过loader发送给你的数据来访问他们.在这一过程中你还以通过一个对象得知当前已加载量和总加载量.

让我们在前一段代码的基础上做一些修改.

现在我们会将当前已加载的字节以字符串的形式读取出.你应该会在output窗口看到原始google页面的html代码.如下所示:
<!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-
1"><title>Google</title><script>window.google={kEI:"xTp8TZq4HpPWtQOd4Kz4Ag",kEXPI:"28479,28501,28595,29014,291
35,29265,29279",kCSI:{e:"28479,28501,28595,29014,29135,29265,29279",ei:"xTp8TZq4HpPWtQOd4Kz4Ag",expi:"28479,28
501,28595,29014,29135,29265,29279"},ml:function(){},kHL:"en",time:function(){return(new 
Date).getTime()},log:function(c,d, 
b){var a=new Image,e=google,g=e.lc,f=e.li;a.onerror=(a.onload=(a.onabort=function(){delete 
g[f]}));g[f]=a;b=b||"/gen_204?atyp=i&ct="+c+"&cad="+d+"&zx="+google.time();a.src=b;e.li=f+1},lc:[],li:0,Toolbe
lt:{}…
 

 

这就意味着我们的逐步的读取字节.这一有趣的特点造就了我们的下一个实例,在加载完毕前通过尽快的解析图像(字节)中的头部(head)信息来重现图像.
// creates a URLStream object 
var stream:URLStream = new URLStream(); 

// listen to the ProgressEvent.PROGRESS event to grab the incoming bytes 
stream.addEventListener ( ProgressEvent.PROGRESS, onProgress ); 
stream.addEventListener ( Event.COMPLETE, onComplete ); 

// download the remote image 
stream.load ( new URLRequest ("http://dl.dropbox.com/u/7009356/IMG_4958.jpg" ) ); 

// store the incoming bytes 
var buffer:ByteArray = new ByteArray(); 

// Loader to display the picture 
var loader:Loader = new Loader(); 

// show it 
addChild ( loader ); 

function onProgress ( e:ProgressEvent ):void 
{ 
   // we keep writing the bytes coming in 
   stream.readBytes ( buffer, buffer.length ); 
   // we clear the previously loaded content 
   loader.unload(); 
   // we inject the bytes to display the image 
   loader.loadBytes ( buffer ); 
} 

function onComplete ( e:Event ):void 
{ 
   trace ("complete"); 
} 
  


我们通过API loadBytes来显示接收到的数据,当我们插入新的字节数据时,FLash Player显示出了其内容.下图展示出了一张未加载完的图像.


然后图像逐步显示直至最终加载完成


现在你可能不太清楚其真正的价值,但是这一实例的确很好的告知了我们可以用URLStream接收到的数据来干什么.就像我们刚刚看到的,loadBytes是一个非常强大的API但是它也有自身的限制.在接下来的部分我们将去探寻为什么有些时候开发者被其困住了.

Loadbytes 的局限性
要记住loadBytes是异步的,所以需要我们需要等到Event.COMPLETE事件之后才可以读取swf的大小,class定义等.下面的代码说明了这一大意:
import flash.utils.ByteArray; 
import flash.display.Loader; 

[Embed(source="library.swf", mimeType="application/octet-stream")] 
var library:Class; 

// instanciate the stream as a ByteArray 
var swfBytes:ByteArray = new library(); 

// instanciate a Loader 
var myLoader:Loader = new Loader(); 

// show the Loader object 
addChild ( myLoader ); 

// loadBytes is asynchronous, we need to wait for the complete event before retrieving content from the loaded 
SWF 
myLoader.contentLoaderInfo.addEventListener ( Event.COMPLETE, onComplete ); 

// inject the embedded stream inside the Loader 
// the SWF is executed automatically 
myLoader.loadBytes(library); 

// handler 
function onComplete ( e:Event ):void 
{ 
   trace("loading complete"); 
} 
  


只有当加载完毕后类定义才可以被获取到:
// handler 
function onComplete ( e:Event ):void 
{ 
   // retrieve a class definition 
   var classDefinition:Class = e.currentTarget.applicationDomain.getDefinition("MyDefinition"): 
}
 

 

在loader对象中的所有种类的文件都必遵从这个限制.有很多开发者企图在加载过程中动态读取一个图像,但是在我们现有的RSL(动态运行时共享库)机制下,图像相关数据的读取必须要等到加载完毕后才可以进行,并且图像的解析是由Flash player进行的:

        
import flash.utils.ByteArray; 
import flash.display.Loader; 

[Embed(source="image.jpeg", mimeType="application/octet-stream")] 
var imageStream:Class; 

// instanciate the stream as a ByteArray 
var jpegBytes:ByteArray = new imageStream(); 

// instanciate a Loader 
var myLoader:Loader = new Loader(); 

// show the Loader object 
addChild ( myLoader ); 

// loadBytes is asynchronous, we need to wait for the complete event before retrieving image dimensions What can you do with bytes ? – Chapter 2 – Everyday bytes 
myLoader.contentLoaderInfo.addEventListener ( Event.COMPLETE, onComplete ); 

// inject the image stream inside the Loader 
myLoader.loadBytes(jpegBytes); 

// handler retrieving the image size  
function onComplete ( e:Event ):void 
{ 
   // outputs : width : 300 height : 400 
   trace ( "width : " + e.currentTarget.width, "height : " + e.currentTarget.height );  
} 

 

因此你也需要一个异步的处理方法.在加载过程中你需要手动的来解析.为此我用 adobe的 Alchemy 写过一个动态的JPEG解码器 (http://www.bytearray.org/?p=1089)
分享到:
评论

相关推荐

    《Flex第一步》书中源代码1

    &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;projectDescription&gt; &lt;name&gt;Example_1&lt;/name&gt; &lt;comment&gt;&lt;/comment&gt; &lt;projects&gt; &lt;/projects&gt; &lt;buildSpec&gt; &lt;buildCommand&gt; &lt;name&gt;...

    本地播放器源码仅供交流

    一个本地播放器的源码,学习学习 ... &lt;content&gt;[This value will be overwritten by Flex Builder in the output app.xml]&lt;/content&gt; &lt;visible&gt;true&lt;/visible&gt; &lt;/initialWindow&gt; &lt;/application&gt;

    Flash/Flex 框架应用 Cairngorm、Mate、PureMVC以及Swiz 的典型例子

    附件是关于 Flash/Flex 几个重要框架 Cairngorm、Mate、PureMVC以及Swiz 的典型例子,由 Tony Hillerson 提供 Homepage: http://insideria.com

    Adobe Flex Builder 3.0官方使用教程

    &lt;br&gt; Contents:&lt;br&gt;&lt;br&gt;Chapter 1: Learning Flex Builder&lt;br&gt;Chapter 2: About Flex Builder&lt;br&gt;Chapter 3: Flex Builder Workbench Basics&lt;br&gt;Chapter 4: Working with Projects&lt;br&gt;Chapter 5: Navigating and ...

    AdobeAirAdobeAIRInstaller part2

    ActionScript &lt;br&gt; HTML / JavaScript / CSS / Ajax &lt;br&gt; PDF 可嵌入任何应用程序中 &lt;br&gt;作为结果,AIR 应用程序可以是:&lt;br&gt;&lt;br&gt; 基于Flash 或 Flex:应用程序根内容(理解为容器)为Flash/Flex (SWF) &lt;br&gt; 基于...

    Flash Sample

    &lt;br&gt;Feature highlight: Date object&lt;br&gt;View the time with this clock.&lt;br&gt; &lt;br&gt;Feature highlight: getTimer&lt;br&gt;An example of how you can build a stopwatch-style timer.&lt;br&gt; &lt;br&gt;Feature highlight: Dynamic ...

    flash/flex画曲线,绘图板

    flash/flex画曲线,绘图板,用代码实现的个画曲线功能,类绘图板,可下载看看,不错的学习案例。

    css用Flex布局制作简易柱状图的实现

    以下是一个用Flex布局的柱状图: ... &lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; CSS: .his_box{ /*盒子

    flash/flex 的aqua皮肤

    flash/flex 的aqua皮肤.类似苹果系统

    Flex 完全自学手册

    &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="14"&gt; &lt;mx:Panel width="262" height="291" layout="absolute" title="ʹԃMXML¶¨ӥة¼�&lt;mx:...

    flex导出excel的代码

    &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"&gt; &lt;mx:Script&gt; &lt;![CDATA[ import mx.controls.CheckBox; import mx.controls....

    flex4cookbook

    pdf文件,书为英文版,内附源码. &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" ...&lt;/s:Application&gt;

    解决flash/flex/as3 访问中文域名时的流错误示例

    来自《潮汕IT男》网站的文章《解决flash/flex/as3 访问中文域名时的流错误》代码示例,地址:http://chenlinsheng.com/?p=990

    flexjava交互

    &lt;source&gt;bean.MoginDemo &lt;/source&gt; &lt;scope&gt;application&lt;/scope&gt; &lt;/properties&gt; &lt;/destination&gt; 3. java package bean; import java.util.*; public class LoginDemo { public String validateLogin(String ...

    使用jquery解析XML示例代码

    xml文件结构:books.xml &lt;?xml version=1.0 encoding=UTF-8?&gt; &lt;root&gt; &lt;book id=1&gt; &lt;name&gt;深入浅出extjs&lt;/name&gt; &lt;author&gt;张三&lt;/author&gt; ...&lt;name&gt;深入浅出flex&lt;/name&gt; &lt;author&gt;王五&lt;/author&gt; &lt;price&gt;108&lt;/p

    <<flex从入门到精通>>(源码)

    很好的学习flex的书籍,适合初学者,我是在书店买的这书,附带的光盘中的源码,希望对你们有帮助

    flex播放mp3

    flex播放mp3源码: &lt;s:BorderContainer x="131" y="147" width="369" height="108"&gt; &lt;s:Label x="83" y="47" text="进度:" width="45"/&gt; &lt;s:HSlider id="hslider1" x="135" y="48" width="221" changeEnd=...

    flex开发对时间控制

    flex 对时间的关注&lt;mx:Script&gt; &lt;![CDATA[ // Event handler for the DateField change event. private function dateChanged(date:Date):void { if (date == null) selection.text = "Date selected: "; ...

    flex柱状图动态切换数据源实例

    该flex应用程序演示了柱状图动态切换数据源 &lt;mx:ColumnChart x="6" y="65" id="columnchart1" showDataTips="true" dataProvider="{list}" height="390" itemClick="onItemClick(event)"&gt; &lt;mx:horizontalAxis&gt; ...

    FDT-flash/flex devtoolkit for eclipse.

    FDT-flash/flex devtoolkit for eclipse. for最新版的 FDT 3.5 beta2

Global site tag (gtag.js) - Google Analytics