SWF文件格式
- 格式:pdf
- 大小:1.12 MB
- 文档页数:27
目录
第一篇文章 ..................................................................................................................... 2
第二篇文章 ..................................................................................................................... 3
第三篇文章 ..................................................................................................................... 6
第四篇文章 ................................................................................................................... 11
第五篇文章 ................................................................................................................... 18
第一篇文章 首先,我创建了一个默认的 SWF 文件,即舞台大小为 550*400,帧频为 12,背景为白色,
仅一帧的文件。首先用UltraEdit打开这个文件,我们可以看见二进制的文件结构:
每行自 ; 号以后(包括 ;
号)的字符都不用理会。首先给出 SWF 文件头的各属性列表:
字段 类型 说明
标识 8位 表示文件是否被压缩("46" F 为没有压缩,"43" C 为被压缩)。
标识 8位 总是 "57" W。
标识 8位 总是 "53" S。
版本号 8位 代表SWF文件的版本(如果是9,就为 "09")。
文件长度 32位 表示文件的大小。
帧大小 RECT结构表示舞台的大小。
帧频 16位 每秒要播放的帧数。
帧数 16位 总共的帧数。
是否压缩标识: 我们从UltraEdit中打开的文件来看,前 3 个字节为 46 57 53,即 FWS,Flash 默认情
况下会压缩 SWF 文件,但是我们的文件为空,所以没有被压缩。
版本号: 第四个字节为 09 表示是用 Flash9 制作的文件,注意是 16 进制,如果是 Flash12(如
果有的话) 制作的,会显示 0C。
文件大小: 第五个字符到第八个字符表示文件大小,为 24 00 00 00,注意是 16 进制,并且低位
在前,表示文件大小是 36 个字节。这里有必要详细的介绍一下,这里表示的文件大小是
没有压缩时的文件大小,如果文件被压缩过(前 3 个字节为 CWS 的话),这里的大小会和
实际大小不一致,会大许多。 再说说文件大小的算法,我专门搞了个没有压缩的文件,大小为 45023 字节(43.9KB),
这里显示为 DF AF 00 00 (压缩后输出文件实际大小为 29.4KB,但是还是显示 DF AF 00 00
数字),那么它是怎么表示文件大小的呢?“16 进制,并且低位在前。”其实这句话已经告诉
我们了,真正的文件大小为 00 00 AF DF 即把这四个字符反过来就行,去掉 0 即 AFDF,
用计算器一看 AFDF 的十进制就是 45023。最大可显示 FF FFFFFF,这表示的大小是 4GB,
即硬盘文件系统 FAT32 支持的单个文件最大的大小。
帧大小: 接下来的是帧大小,表示舞台的大小,是文件头里最麻烦的了,网上资料暴少,官方文件
说得太简单(其实是我英语水平太简单-_-!),先暂时放下,如果要看帧大小算法请点击这里。
根据介绍可以推出帧频与帧数的地址。
帧频: 提示为 16 位,且高位在前,得知地址为第二行的 1 和 2,即 00 0C,同样去掉 0,
得 C,计算器转换为十进制为 12。 帧数: 提示为 16 位,且低位在前,紧跟帧频就是第二行的 3 和 4 了,即 01 00,倒过来 00
01 转换后是 1。
SWF 文件头介绍完了,但是我们发现文件还有近一半的数据,这是因为 SWF 文件头的
各属性仅仅能提供 SWF 文件的基本属性,下面是一个 SWF 文件的基本构造:
FileAttributes标签(必有标签):
我们看见紧跟 Header(文件头) 的是名为FileAttributes的标签,FileAttributes标签仅仅
是 Flash8 及更早版本输出的 SWF 文件里必须的内容,但是也存在 Flash9 输出的 SWF
文件里。开始的 44 11 为其标签,后面紧跟的 08 00 00 00 为内容,FileAttributes的标签
前面的 08 比较复杂,包含 5 个属性,后面的 00 00 00 则是必须设置为 0。
SetBackgroundColor标签(必有标签):
背景色设定的标签,开始的 43 02 为其标签,后面紧跟的 FF FFFF为背景色,为 RGB 格
式,你可以改成 FF 00 00,另存为一个新 SWF 文件看看背景色是不是变成红色了。 ShowFrame标签(必有标签):
SWF 文件的倒数第二个标签,显示为 40 00。
End 标签(必有标签):
SWF 文件的倒数第一个标签,显示为 00 00,表示文件已经结束。
注意: 被压缩过的 SWF 文件(即第一个字符为 43)或被加密过的文件,是无法正常显示的,必
须先将其解压,才能在UltraEdit里正常显示其 2进制源码。 被压缩过的 SWF 文件是从文件头之后开始压缩的,文件头能正常显示。
第二篇文章
初次接触这个问题是为了完善我自己做的flashplayerV1.02的最后一个功能,也就是EXE<->SWF的转换功能.当时并不知道文件转换机制是什么,更对SWF文件格式也一窍不
通.^_^我相信也有好多朋友和我遇到了一样的问题吧,以下就我自己积累的一些经验,以及
别人对我的帮助.来谈一谈这个问题.
首先.我们来看一下SWF文件头格式:(以下为我的资料收集) 以一个实际的SWF文件头为例: 46 57 53 05 B4 66 07 00 70 00 0F A0 00 00 BB 8000 0C 9F 03
1.字节 1-3 (46 57 53): SWF文件头标志,FWS表示未压缩,CWS表示压缩的SWF文
件,需要从第9个字节起用ZLib解压 2.字节 4 (05): Flash文件的版本,这里表明它是用Flash5生成的
3.字节 5-8 (B4 66 07 00):一个Integer表示文件的长度,低在前,高在后,这里是
$000766B4 = 485044字节,这里应该等于未压缩的SWF文件实际大小或压缩过的SWF解
压后的长度+文件头(8字节) 4.字节 9 - 。。。: SWF显示区域,(左上角坐标,右下角坐标),用下面的方法计算得
到:第9字节前5位(70 shr 3 = 14),以后的字节以14位进行分割,所需位数为 14*4+5 = 61,需要 8 个字节来表示,那么: 70 00 0F A0 00 00 BB 80 [01110][00000000000000][01111101000000][00000000000000][01011101110000]000 [01110][00000000000000][01111101000000][00000000000000][01011101110000]000 14 0 8000 0 6000因为Flash的坐标是TWIP格式的,需要除以20的,所以实际为
(0,400,0,300)
5.接下来的两字节 (00 0C):表示帧速率,前一字节表示小数位,后一字节表示整数位,不
过一般极少有小数位的帧率,所以一般我们只计整数就可以了,这里 $0C = 12,即每秒12
帧再接下来的两字节 (9F 03):表示总帧数,WORD类型,$039F=927帧,与ShockwaveFlash.TotalFrames得到的数值是一样的。
6.再后面的数据是SWF的实体数据
接着:我们来看EXE文件的真正面目.其实EXE的SWF并不存在什么文件格式转换的问
题,SWF文件之所以能变为EXE文件,无非是加入了一些流的操作罢了.下面让我们看看EXE
文件的由来,简单的说: EXE格式的SWF文件不过是一个Flash播放器程序后面跟着一个SWF文件,两个文件写在一起,然后再在文件末尾写入SWF文件的大小和“FA123456”标示。
故SWF->EXE的转换机制其实就这么简单.
而EXE->SWF呢,无非就是从文件末尾得到内嵌的SWF文件大小,然后新建一个空白的扩
展名为.swf的文件,把内嵌的SWF文件写入这个新文件就可以了!
明白的这些以后,我想就SWF与EXE的转换也就不难了吧.(关键是一些流操作)
以下我给出一些流操作的函数及用法:
一、Delphi中流的基本概念及函数声明
在Delphi中,所有流对象的基类为TStream类,其中定义了所有流的共同属性和方法。 TStream类中定义的属性介绍如下:
1. Size:此属性以字节返回流中数据大小。
2. Position:此属性控制流中存取指针的位置。
Tstream中定义的虚方法有四个:
1. Read:此方法实现将数据从流中读出。函数原形为:
Function Read(varBuffer;Count:Longint):Longint;virtual;abstract;
参数Buffer为数据读出时放置的缓冲区,Count为需要读出的数据的字节数,该方法返回值
为实际读出的字节数,它可以小于或等于Count中指定的值。 2. Write:此方法实现将数据写入流中。函数原形为:
Function Write(varBuffer;Count:Longint):Longint;virtual;abstract;