RT,看了SWF文件格式说明,感觉头有点大

解决方案 »

  1.   

    呵呵,除了flash 的sdk还有什么办法,我也想知道
      

  2.   

    用文件流
    我有获取一般文件信息的代码
    但是对于CWS(压缩过的)格式的无法取得
      

  3.   

    呵呵,终于做完了,忙活了一个下午,也该下班了,那个从数组取数的函数也不知道对不对,下班先
    procedure TMain.Button1Click(Sender: TObject);
    var
        FileStream:TFileStream;
        FWS:Array[0..2] of char;
        Version:Byte;
        FileLength:LongWord;
        EachElementBitCount,RectBitCount,OrgData:Byte;
        RectByteCount:integer;
        RectArr:Array of Byte;
        FrameRate:Dword;
        FrameCount:Word;function GetValueFromByteArr(AIndex:Byte):Dword;
    var iStartBit,iEndBit,iStartByte,iEndByte,iLength,ShrBitCount:integer;
    begin
        iStartBit:=5+(AIndex-1)*EachElementBitCount+1;
        iEndBit:=iStartBit+EachElementBitCount-1;
        iStartByte:=iStartBit div 8;
        iEndByte:=(iEndBit div 8);
        iLength:=iEndByte - iStartByte+1;
        Move(RectArr[iStartByte],Result,4);
        ShrBitCount:=8*(4-iLength)+(8- (iendBit mod 8));
        Result:=Result shr ShrBitCount;
    end;begin   Memo1.Lines.Clear;
       FileStream:=TFileStream.Create('c:\1.swf',fmOpenRead);   FileStream.Read(Fws,3);
       Memo1.Lines.Add('FWS:'+FWS);
       FileStream.ReadBuffer(Version,1);
       Memo1.Lines.Add('Version:'+Inttostr(Version));
       FileStream.ReadBuffer(FileLength,4);
       Memo1.Lines.Add('File Length:'+inttostr(FileLength));   FileStream.ReadBuffer(OrgData,1);
       EachElementBitCount:=OrgData shr 3;
       Memo1.Lines.Add('nBits:'+inttostr(RectBitCount));   RectBitCount:=5+4*EachElementBitCount;
       while (RectBitCount mod 8)<>0 do
           Inc(RectBitCount);
       RectByteCount:=(RectBitCount div 8)-1;   SetLength(RectArr,RectByteCount+1);
       RectArr[0]:=OrgData;   FileStream.ReadBuffer(RectArr[1],RectByteCount);   Memo1.Lines.Add('XMin:'+inttostr(GetValueFromByteArr(1)));
       Memo1.Lines.Add('XMax:'+inttostr(GetValueFromByteArr(2)));
       Memo1.Lines.Add('yMin:'+inttostr(GetValueFromByteArr(3)));
       Memo1.Lines.Add('XMax:'+inttostr(GetValueFromByteArr(4)));   FileStream.ReadBuffer(FrameRate,2);
       Memo1.Lines.Add('Frame Rate:'+inttostr(FrameRate));
       FileStream.ReadBuffer(FrameCount,2);
       Memo1.Lines.Add('Frame Count:'+inttostr(FrameCount));   FileStream.Free;
       SetLength(RectArr,0);end;
      

  4.   

    楼上的代码一看就不能读取CWS格式的文件(压缩过的)
    读FWS应该是正确的CWS要从第9字节起用zlib解压.过两天放出代码.
      

  5.   

    哦,没注意看CWS的格式,等我在看看CWS的格式
      

  6.   

    搂主正解,CWS从Rect后的数据要用Zlib解压后才能读取,奇怪啊,Flash Sdk只字未提CWS。
    我就不多事了,还是静候LZ的代码
      

  7.   

    国外网站上找到的代码,整理了一下,并加上了读背景色tag的部分unit uFlash;interfaceuses
      windows, SysUtils, Classes, Zlib;type
      TBitWidth = Integer;
      TSWFRect = packed record
        Xmin: Integer;                                          // in twips
        Xmax: Integer;                                          // in twips
        Ymin: Integer;                                          // in twips
        Ymax: Integer;                                          // in twips
      end;  TSWFColor = packed record
        R : Byte;
        G : Byte;
        B : Byte;
        RGB : string;
      end;  TSWFHeader = packed record
        Signature: array[0..2] of char;
        Version: byte;
        FileLength: cardinal;
        FrameSize: TSWFRect;
        FrameRate: byte;
        FrameRateRemainder: byte;
        FrameCount: cardinal;
        BkColor : TSWFColor;
      end;  TTagHandle  = record
        ID  : Integer;
        Length  : Integer;
        HandleLength  : Integer;
      end;
      
    function GetSwfFileHeader(const FileName: string; var Header: TSWFHeader): boolean;implementationfunction ReadNBits(const Buffer; Position: longint; Count: TBitWidth): longint;
    var
      I, B: longint;
    begin
      Result := 0;
      B := 1 shl (Count - 1);
      for I := Position to Position + Count - 1 do
      begin
        if (PByteArray(@Buffer)^[I div 8] and (128 shr (I mod 8))) <> 0 then
          Result := Result or B;
        B := B shr 1;
      end;
    end;function ReadTagHandle(const Buffer; Position : Longint): TTagHandle;
    var
      v : Smallint;
    begin
      v :=  PSmallint(@PByteArray(@Buffer)^[Position])^;
      Result.ID :=  v shr 6;
      v :=  v shl 10;
      Result.Length :=  v shr 10;
      if Result.Length = $FFFFFF then
      begin
        //长tag
        Result.HandleLength :=  6;
        Result.Length :=  PInteger(@PByteArray(@Buffer)^[Position + 2])^;
      end
      else
        Result.HandleLength :=  2;
    end;function GetSwfFileHeader(const FileName: string; var Header: TSWFHeader): boolean;
    const
      BuffSize = 64;
    var
      Buffer: PByteArray;
      NBitsField: byte;
      Poz: longword;
      FileStream: TFileStream;
      MemStream: TMemoryStream;
      ZStream: TDecompressionStream;
      Tag : TTagHandle;
    begin
      Result := False;
      if not FileExists(FileName) then
        Exit;
      FileStream := TFileStream.Create(FileName, fmOpenRead);
      try
        FileStream.Position := 0;
        if FileStream.Size > 22 then
        begin
          GetMem(Buffer, BuffSize);
          try
            FileStream.Read(Header, 8);
            if (Header.Signature = 'CWS') and (Header.Version >= 6) then
            begin
              Result := True;
              MemStream := TMemoryStream.Create;
              try
                MemStream.CopyFrom(FileStream, FileStream.Size - 8);
                MemStream.Position := 0;
                ZStream := TDecompressionStream.Create(MemStream);
                try
                  ZStream.Read(Buffer^, BuffSize);
                finally
                  ZStream.Free;
                end;
              finally
                MemStream.Free;
              end;
            end
            else
            begin
              FileStream.Read(Buffer^, BuffSize);
              Result := Header.Signature = 'FWS';
            end;        if Result then
              with Header do
              begin
                Poz := 0;
                NBitsField := TBitWidth(ReadNBits(Buffer^, Poz, 5));
                Inc(Poz, 5);
                FrameSize.Xmin := Integer(ReadNBits(Buffer^, Poz, NBitsField));
                Inc(Poz, NBitsField);
                FrameSize.Xmax := Integer(ReadNBits(Buffer^, Poz, NBitsField));
                Inc(Poz, NBitsField);
                FrameSize.Ymin := Integer(ReadNBits(Buffer^, Poz, NBitsField));
                Inc(Poz, NBitsField);
                FrameSize.Ymax := Integer(ReadNBits(Buffer^, Poz, NBitsField));
                Inc(Poz, NBitsField);
                NBitsField := Poz mod 8;
                Poz := Poz div 8;
                if (NBitsField > 0) then
                  Inc(Poz);
                FrameRateRemainder := Buffer^[Poz];             // 8.[8]
                FrameRate := Buffer^[Poz + 1];
                FrameCount := Buffer^[Poz + 2] or (Buffer^[Poz + 3] shl 8);
                Inc(Poz, 4);
                Tag :=  ReadTagHandle(Buffer^, poz);
                while Tag.ID <> 9 do
                begin
                  Inc(Poz, Tag.Length + Tag.HandleLength);
                  Tag :=  ReadTagHandle(Buffer^, Poz);
                end;
                BkColor.R := Buffer^[Poz + 2];
                BkColor.G := Buffer^[Poz + 3];
                BkColor.B := Buffer^[Poz + 4];
                BkColor.RGB :=  StringReplace(
                    Format('%2x%2x%2x', [BkColor.R, BkColor.G, BkColor.B]),
                    ' ', '0', [rfReplaceAll]); 
              end;      finally
            FreeMem(Buffer);
          end;
        end;
      finally
        FileStream.Free;
      end;
    end;end.