zoukankan      html  css  js  c++  java
  • 利用AS3的ByteArray解析SWF的尺寸

    AS3的ByteArray可以用来操作二进制。使用它,我们就获取加载进来的SWF的尺寸。

    首先要了解下SWF的文件结构,可以下载官方的PDF看下。

    用UltraEdit32打开一个SWF,会看到第一个字节是43或46,这是16进制,对应的字符就是C或F,其中C表示压缩过的,F表示未压缩的。

    第二个字节和第三个字节是固定的57 53.

    接着1个字节表示Flash版本,比如08,就是Flash8的,0A就是Flash10的。

    后面4个字节表示Flash文件大小(未压缩时的大小)

    到此需要暂停一下。我们最开始就已经知道了这个文件是否是压缩过的,如果是已经压缩过的,需要对文件尺寸之后的字节进行解压缩,就是利用ByteArray.uncompress()。如果是未压缩的就略过这一步。

    接下来将是一个Rect结构。它占用的字节数是不固定的。它由5部分组成,第一个是len,后面4个数是xmin,xmax,ymin,ymax。这4个数所占位数相同,都是len。

    len由rect的前5位二进制决定。

    举个例子,假如我们看到的Rect开始的二进制是这样70 00 0F A0 00 00 ……….

    首先取第一个字节70,二进制就是0111 0000,前5位就是(01110)2= (14)10,就是10进制的14,也就是说后面的4个数xmin,xmax,ymin,ymax每个数都占14位,这样14*4=56;

    而第一个字节还剩下3位,56-3=53.也就是说除了第一个字节外,我们还需要Math.ceil(53/8) = 7个字节,这里为什么要向上取整?因为字节对齐的关系。就是说,你用53位跟56位占用的空间是一样的,不够56也会补够56.

    OK,原理就是这样,具体怎么做呢

    private function calc_size(byte:ByteArray):void {   var char:String = String.fromCharCode(byte.readByte()); // C or F byte.readByte(); // W byte.readByte(); // S byte.readByte(); // version byte.readUnsignedInt(); // file size 32 bit if(char == "C") { var tmpByte:ByteArray = new ByteArray();
    				byte.readBytes(tmpByte);
    				byte = tmpByte;
    				byte.position = 0;
    				byte.uncompress(); } var bit:uint = byte.readUnsignedByte(); var bitLen:uint = bit >> 3; var bits:uint = bitLen * 4;
    			bits = Math.ceil((bits - 3) / 8); var num:int = bit & 0x07; var readed:int = 3; var sizeArr:Array = []; var sizeId:int = 0; var ava:int = 0; var avaNum:uint; var readCount:int = 0;
      do { if(ava == 0) { ava = 8;
    					readCount ++;
     
    					avaNum = byte.readUnsignedByte();
      }   if(readed < bitLen) { var offset:int = bitLen - readed; if(offset > ava) { num = (num << ava) | avaNum;
     
    						readed += ava;
    						ava = 0;
      } else { num = (num << offset) | (avaNum >> (ava - offset));
    						avaNum = avaNum - (avaNum >> (ava - offset));
     
    						ava -= offset;
    						readed += offset;
      }   } else { sizeArr[sizeId] = num;
    					sizeId ++; if(sizeId == 4) { break; } num = 0;
    					readed = 0; } }while(true);
    			srcW = sizeArr[1] / 20;
    			srcH = sizeArr[3] / 20; }

    我们可以注意到最后求出的尺寸都做了除以20的处理,这是因为,我们求出来的数单位是twip,1 pixel = 20 twips。所以除以20就是我们熟知的像素了。

  • 相关阅读:
    Boost线程库学习笔记
    sizeof运算符
    用法char ch=getchar()正确性详解
    C语言中的缓冲输出
    算术运算的溢出行为 and 一个数内存中表示1的个数
    ARP、RARP、ICMP、ping
    http和https协议
    关于宋词频率统计(R语言)
    Backbone.js API中文文档
    腾讯小Q书桌图标怎么实现的啊?
  • 原文地址:https://www.cnblogs.com/lancidie/p/5104272.html
Copyright © 2011-2022 走看看