AS3的ByteArray能夠用來操做二進制。使用它,咱們就獲取加載進來的SWF的尺寸。 ui
首先要了解下SWF的文件結構,能夠下載官方的PDF看下。 spa
用UltraEdit32打開一個SWF,會看到第一個字節是43或46,這是16進制,對應的字符就是C或F,其中C表示壓縮過的,F表示未壓縮的。 code
第二個字節和第三個字節是固定的57 53. ip
接着1個字節表示Flash版本,好比08,就是Flash8的,0A就是Flash10的。 it
後面4個字節表示Flash文件大小(未壓縮時的大小) io
到此須要暫停一下。咱們最開始就已經知道了這個文件是不是壓縮過的,若是是已經壓縮過的,須要對文件尺寸以後的字節進行解壓縮,就是利用ByteArray.uncompress()。若是是未壓縮的就略過這一步。 function
接下來將是一個Rect結構。它佔用的字節數是不固定的。它由5部分組成,第一個是len,後面4個數是xmin,xmax,ymin,ymax。這4個數所佔位數相同,都是len。 class
len由rect的前5位二進制決定。 stream
舉個例子,假如咱們看到的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就是咱們熟知的像素了。