用Flash8新建一个fla文档,画布尺寸设为550*400,帧速为24帧/s,背景色为白色。第一帧的帧标签命名为"start",在动作面板上写上AS Code
第2帧命名为"end",动作面板里写AS Codestop();
。然后发布设置里:发布成FlashPlayer8,不压缩影片。prevFrame();
然后保存、输出swf。用
UltraEdit32打开输出的swf,看到的画面如下图所示
下面我们来分析一些这些16进制数字的意义。
对于SWF中数据格式及数据存储方式不明白,请先到swf文件格式--基本数据类型中看看。
我们先看下关于SWF文件头的官方说明
| 区域 | 数据类型 | 含义 |
| 标识 | UI8(8位二进制无符号整数) | "F"表示该文件是未压缩的 "C"表示压缩文件(SWF6及后续版本支持) |
| 标识 | UI8 | 总是"W" |
| 标识 | UI8 | 总是 "S" |
| 版本 | UI8 | SWF文件版本 |
| 文件大小 | UI32 | 文件字节大小 |
| 画面尺寸 | RECT | 以twips为单位 |
| 帧速 | UI16 | 8.8形式的定点小数 |
| 总帧数 | UI16 | 总帧数 |
OK了,对应着它我们来分析下刚才生成的文件
| 数据 | 含义 |
| 46 | "F",表示未压缩的 |
| 57 | "W" |
| 53 | "S" |
| 08 | SWF文件版本为8 |
| 4C 00 00 00 | 文件大小为 4*16+12=76字节 |
再往后就是画布尺寸了,它是一个RECT结构的数据,我们先看下RECT结构说明:
| 名字 | 类型 | 含义 |
| Nbits | UB[5] | 表示每个数字必须的二进制位数 |
| Xmin | SB[Nbits] | x最小值 |
| Xmax | SB[Nbits] | x最大值 |
| Ymin | SB[Nbits] | Y最小值 |
| Ymax | SB[Nbits] | Y最大值 |
我们生成的这个SWF文件中的数据是78 00 ...,我们先取前5位二进制,先确定好数据位数。78的二进制形式是:0111 1000,取前5位就是0111 1,它表示的十进制数是15=8+4+2+1,也就是说,Xmin,Xmax,Ymin,Ymax都要15位二进制数来表示,那么后面还要至少取15*4 - 3 =57位,又因为要符合
字节对齐的规则,所以要取64位,也就是取 78 00 05 5F 00 00 0F A0 00,
然后我们把它转换成二进制后,在按照15位分割
0111 1||000 0000 0000 0000 ||0101 0101 1111 000||0 0000 0000 0000 00|| 00 1111 1010 0000 0||000 0000
然后我们可以算出
Xmin = (000 0000 0000 0000)2=(0)10
Xmax = (0101 0101 1111 000)2= (11000)10
Ymin = (0 0000 0000 0000 00)2 =(0)10
Ymax = (00 1111 1010 0000 0) 2= (8000)10
你也许会产生疑问,我们明明设定的画面尺寸是550*400的啊,这里为什么算出来的是11000 * 8000的啊?!别忘了,这里算出来的数字是以
twips为单位的,一般情况下,1 twip等于1/20象素。
OK,接着往后解析,接下来就是帧速和帧数了,呵呵
| 数据 | 含义 |
| 00 18 | 表示帧速为16+8=24帧/S |
| 02 00 | 帧数为2帧(再次提醒下,这是 little-endian小尾存储噢) |
OK.到此SWF文件头就结束了,接下来就是一个一个的Tag了。
我们先取16位:44 11,将小尾字节顺序转换成大尾顺序,就是11 44,然后取它的高10位是(0001 0001 01)2=(69)10,取它的低6位是(00 0100)2=(4)10.根据高10位的69,查询swf文件中的tag值和action值,可以知道TagType为69的是
FileAttribute Tag。低6位的值4表示这个Tag数据大小占4个字节。因此我们取出接下来的后4个字节为:00 00 00 00,不要看它仅仅是0,其实它是有意义的,我们看下FileAttributes Tag的结构说明
| 域 | 数据类型 | 含义 |
| Tag头 | RECORDHEADER | TagType=69 |
| Reserved | UB[3] | 总是0 |
| hasMetaData | UB[1] | 为1表示含有MetaData标签 为0表示不含 |
| Reserved | UB[3] | 总是0 |
| UseNetWork | UB[1] | 如果为1,则在本地加载时该文件有网络权限。为0,则在本地加载时该文件只有本地权限。 |
| Reserved | UB[24] | 总是0 |
这里说下FileAttributes Tag只在8及后续版本中有。
OK,Go on....
取下一个Tag,依然取2个字节43 02,转化成02 43,然后高十位=(0000 0010 01)2=(9)10,低6位=(00 0011)2=(3)10,高10位的9表明这是一个
SetBackgroundColor tag,低6位的3表明数据占3个字节,OK,我们取出后续的3个字节是 FF FF FF,知道了吧,这就是我们设置的背景颜色:白色。
再取下一个Tag,3F 03,转化成03 3F,高十位=(0000 0011 00)2=(12)10,低6位=(11 1111)2=(63)10,高十位的12表示这是个
DoAction标签,低6位的63表明数据长度有后续的4个字节决定,OK,我们取后续的4个字节为02 00 00 00,它表明这个Tag的数据长度占2个字节,OK,我们再取后续的2个字节是07 00,07表示Action代码,查Action代码就可以知道它表示的Action语句是
ActionStop,也就是我们写在第一帧的代码AS Code
,呵呵,亲切吧~。07后面的00,就表示DoAction Tag结束了。stop();
Next Tag,FF 0A,转换成 0A FF,高十位=(0000 1010 11)2=(43)10,低6位=(11 1111)2=(63)10,高十位的43表明这是一个
FrameLabel标签,也就是我们所说的帧标签。低6位的63表明数据大小由后续的4个字节指明,我们取出后续的4个字节为06 00 00 00,也就说该Tag的数据占6个字节,OK,继续取后续的6个字节,73 74 61 72 74 00,呵呵,将16进制值转换成字符串,就是"start",00,是字符串结束标志。
Next Tag ,40 00,转换成 00 40,高十位=(0000 0000 01)2=(1)10,低6位=(00 0000)2=(0)10,高十位的1表明这是一个
ShowFrame Tag,也就是说当前帧的内容都已经准备好了,可以显示当前帧了。
NextTag , 3F 03,噫,很熟悉的样子,不错,前面刚刚遇到过吗,在出现AS Code
的地方啊。这就是一个stop();
DoAction Tag,并且数据大小由后续4个字节表明,取后续4个字节:02 00 00 00,呵呵,跟上面的一样,接着取2个字节:05 00,05 表示的Action代码是
ActionPrevFrame,也就是我们说的AS Code了。00表示DoActionTag结束了。prevFrame();
Next Tag,FF 0A,呵呵,这也是刚刚出现的,表明这是一个
FrameLabel标签,也就是我们所说的帧标签。低6位的63表明数据大小由后续的4个字节指明,我们取出后续的4个字节为04 00 00 00,也就说该Tag的数据占4个字节,OK,继续取后续的4个字节,65 6E 64 00,呵呵,将16进制值转换成字符串,就是"end",00,是字符串结束标志。
Next Tag,40 00,转换成 00 40,高十位=(0000 0000 01)2=(1)10,低6位=(00 0000)2=(0)10,高十位的1表明这是一个
ShowFrame Tag,也就是说当前帧的内容都已经准备好了,可以显示当前帧了。
Next Tag 00 00,不用转换了,呵呵,高十位是0,低6位也是0,表明这是个
EndTag,表示什么意义就不用我说了吧。
OK,一个简单的SWF文件就解析完了,好累啊。。擦把汗,再喝口水。。。