flash swf 文件宽高修改

                    flash swf 文件宽高修改VC实现

最近因为项目需求,学习了flash as3.0来做了一个特定功能的动画。

开发工具CS6,格式选了swf9,生成的swf放到web服务器上,用户通过浏览器加载运行。

该swf档内完全由as3.0脚本构成。

做过flash的人知道,IDE上有界面可以设置该swf的舞台宽高,这个生成swf文件时会编译进去。

加载该swf的htm文档内会设置该web将提供怎样的宽高来展示该swf,同时会设置对齐方式。

如果swf的宽高和htm设置的宽高不一致的话,那么你要展示的swf内容的原点就不是web页上展示swf的框的left-top。

因为项目最终将提供给各种用户,所以无法提前知道用户期望的舞台宽高。

这里就产生了一个需求:可不可以修改之前做好的swf文件内的舞台宽高?

这样就可以保证htm展示swf的框的宽高和swf档的宽高一样,两个原点就重合。

 

 

通过查找swf file format specification version 10文档发现,

SWF file structure

<Header><fileattributes tag><tag><tag>...<end tag>

而<Header>里边就放了舞台宽高。

swf file第9个字节开始是一个RECT结构,里边放舞台宽高。

swf file前4个字节是标示文件格式,包括是否压缩deflate

swf file第5到第8字节是整个swf文件的长度,实际试验发现是指未压缩前的长度。

RECT是一个奇怪的定义,头5个bit是说用多少bit来表示xMin\xMax\yMin\yMax4个参数,试验发现每个参数用15bit表示。

当然程序可以计算(5+bit_sum*4)/8,如果有余数就加1。

如果swf是经过deflate压缩的话,那么是从第9个字节开始压缩的,也就是RECT开始压缩,所以需要解压缩,重新计算后再用deflate压缩重组。

 

代码大致是这样:

1 二进制打开目标swf文件,将所有内容都读取到内存BYTE数组里头。

2 头四个字节可以判断是否经过deflate压缩,接下来4个字节是未压缩前的swf文件长度

3 利用zlib的uncompress函数解压缩第9个字节后的内容到新的BYTE数组里头。

4 根据RECT的格式定义,解析当前的xMin\xMax\yMin\yMax和RECT所占用的字节数。

5 根据RECT的格式定义,制作你想要设置的xMin\xMax\yMin\yMax和计算RECT所占用的字节数。

6 重新计算新的swf文件的长度,并修改头8个字节后4个字节表示文件长度,如果新旧RECT字节数一样就不需要重新计算修改。

7 将新的RECT和去掉旧的RECT后的数据合并,然后利用zlib的compress函数压缩文件。

8 将修改长度后的8个字节和压缩过后的字节组合,写到新的文件里,文件扩展名swf。

 

下面是测试代码:

//以下代码针对经deflate压缩的swf9文件
 CxIOFile hFile;
 bool ret = hFile.Open("D:\\FlaPrj\\flash.swf","r+b");
 if(!ret)return;
 long size = hFile.Size();
 BYTE *prbyte = new BYTE[size];
 hFile.Read(prbyte,size,1);
 DWORD dwswflen = prbyte[4] | (prbyte[5]<<8) | (prbyte[6]<<16) | (prbyte[7]<<24);
 unsigned long deflen = dwswflen-8;
 BYTE *pwbyte = new BYTE[deflen];
 //解压缩
 uncompress(pwbyte,&deflen,&prbyte[8],size-8);
 //改变宽高 max range:1000*1000
 {
  WORD flashwidth = 480;
  WORD flashheight = 500;
  WORD xMin=0*20;
  WORD xMax=flashwidth*20;
  WORD yMin=0*20;
  WORD yMax=flashheight*20;
  
  memset(pwbyte,0,9);
  pwbyte[0] |=   0x78+((xMin>>12)&0x7);
  pwbyte[1] |=   ((xMin>>4)&0xff);
  pwbyte[2] |= ((xMin<<4)&0xf0);
  pwbyte[2] |=  ((xMax>>11)&0xf);
  pwbyte[3] |=  ((xMax>>3)&0xff);
  pwbyte[4] |=  ((xMax<<5)&0xe0);
  pwbyte[4] |=  ((yMin>>10)&0x1f);
  pwbyte[5] |=  ((yMin>>2)&0xff);
  pwbyte[6] |=  ((yMin<<6)&0xc0);
  pwbyte[6] |=  ((yMax>>9)&0x3f);
  pwbyte[7] |=  ((yMax>>1)&0xff);
  pwbyte[8] |=  ((yMax<<7)&0x80);
 }
 //再压缩
 BYTE *prcbyte = new BYTE[deflen];
 compress(prcbyte,&deflen,pwbyte,deflen);

 hFile.Close();
 //保存新的文件
 ret = hFile.Open("D:\\FlaPrj\\flash1.swf","wb");
 if(!ret)goto Exit;
 hFile.Write(prbyte,8,1);
 hFile.Write(prcbyte,deflen,1);
 hFile.Close();
Exit: 
 delete[] prcbyte;
 delete[] prbyte;
 delete[] pwbyte;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值