感谢“温柔刀客”的努力,找到一篇不错的Flash编程文章,也感谢文章的作者,解决了我一个困惑了很久的问题,呵呵~~~
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.
=====================
一个运行实例:
procedure TForm1.Button4Click(Sender: TObject);var Head: TSWFHeader; Xmin, Ymin, XMax,YMax:integer;begin M.Clear; if not FIleExists(Edit1.Text) then exit; if not GetSwfFileHeader(Edit1.Text, Head) then SHowmessage('读取出错'); //注意需要 div 20 才得到真正的像素大小 //XMin:=Head.FrameSize.Xmin div 20; XMax:=Head.FrameSize.Xmax div 20; //YMin:=Head.FrameSize.Ymin div 20; YMax:=Head.FrameSize.Ymax div 20; //M.Lines.Add(inttostr(XMin)); M.Lines.Add('当前影片的长是:'+inttostr(XMax)); //M.Lines.Add(inttostr(YMin)); M.Lines.Add('当前影片的宽是:'+inttostr(YMax));end;