熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

Delphi 中壓縮流和解壓流的應用

2013-11-23 17:34:56  來源: Delphi編程 
    軟件開發者不免都要遇到壓縮數據的問題!經常使用Delphi的朋友都知道它為我們提供了兩個流類(TCompressionStream和TDecompressionStream)來完成數據的壓縮和解壓縮但美中不足的是該流在Delphi 的幫助中沒有詳細的說明使得它們在使用起來有一定得困難其實在Delphi系統中提供了這兩個類的源代碼和庫保存在Delphi 光盤的\Info\Extras\Zlib\ Src和\Info\Extras\Zlib\Obj目錄中(其中OBJ錄中保存的是庫Src目錄中保存的是源代碼感興趣的朋友可以看看)本人在使用的過程中對它們有了一定的了解

    一 類的說明

     基類 TCustomZlibStream類TCustomZlibStream 是類TCompressionStream和TDecompressionStream 類的基類它主要有一個屬性 OnProgress在類進行壓縮或解壓縮的過程中會發生這個的事件 它的定義如下

    Procedure OnProgress (Sender: TObject); dynamic;

     壓縮類TCompressionStream類TCompressionStream除了繼承了基類的 OnProgress 屬性外又增加了一個屬性CompressionRate它的定義如下

    Property CompressionRate: Single read GetCompressionRate;通過這個屬性可以得到壓縮比

    它的幾個重要的方法定義如下

    Constructor TCompressionStreamCreate (CompressionLevel: TCompressionLevel; Dest: TStream);

    其中TcompressionLevel(壓縮類型)它由如下幾個定義

    ① clNone 不進行數據壓縮

    ② clFastest進行快速壓縮犧牲壓縮效率

    ③ clDefault進行正常壓縮

    ④ clMax 進行最大化壓縮犧牲速度

    Dest目的流用於存放壓縮過的數據

    Function TCompressionStreamWrite (const Buffer; Count: Longint): Longint;

    其中Buffer需要壓縮的數據

    Count: 需要壓縮的數據的字節數

    函數返回寫入流的字節數

    壓縮類TCompressionStream的數據只能是寫入的如果試圖從其內部讀取數據將發生一個Error 異常需要壓縮的數據通過方法 Write寫入流中在寫入的過程中就被壓縮並保存在由構造函數提供的內存流(TmemoryStream)中同時觸發 OnProcess 事件

     解壓縮類 TDecompressionStream :和壓縮類TcompressionStream 相反它的數據是只能讀出的如果試圖往其內部寫數據將發生一個Error 異常它的幾個重要方法定義如下

    構造函數Constructor Create(Source: TStream);

    其中Source 是保存著壓縮數據的流

    Function Read(var Buffer; Count: Longint): Longint;

    數據讀出函數Buffer 存數據緩沖區

    Count: 緩沖區的大小

    函數返回讀出的字節數

    數據在讀出的過程中數據被解壓縮並觸發 OnProcess 事件

    二 類的使用

    通過類TCompressionStream和TdecompressionStream的配合使用我們可以非常方便地完成數據的壓縮和解壓下面就是本人在編寫屏幕拷貝程序中的使用例子

    Procedure TClientFormGetScreen;
    Var
    SourceDCDestDC:HDC;
    Bhandle:HBITMAP;
    BitMap:TBitMap;
    BmpStreamDeststream:TMemoryStream;
    SourceStream:TCompressionStream;
    Count:Integer;
    Begin
    SourceDC:=CreateDC(displaynil);
    {得到屏幕的 DC}
    DestDC:=CreateCompatibleDC(SourceDC);
    {建立臨時 DC}
    Bhandle:=CreateCompatibleBitmap(SourceDCScreenWidth ScreenHeight);
    {建立位圖}
    SelectObject(DestDCBhandle);
    {選擇位圖DC}
    BitBlt(DestDCScreenWidth ScreenHeightSourceDCSRCCOPY);
    {拷貝整個屏幕}
    BitMap:=TBitMapCreate;
    BitMapHandle := Bhandle;
    {保存屏幕位圖到 BitMap中}
    BmpStream:=TMemoryStreamCreate;
    BitMapSaveToStream(BmpStream);
    {建立位圖數據的內存流}
    count:=BmpStreamSize;
    {保存位圖的大小}
    DestStream:=TMemoryStreamCreate;
    {目標流保存壓縮數據}
    SourceStream:=TCompressionStreamCreate(clMax DestStream);
    {構建壓縮流采用最大化壓縮並保存到目標流中}
    try
    BmpStreamSaveToStream(SourceStream);
    {壓縮位圖流}
    SourceStreamFree;
    {完成壓縮釋放壓縮流}
    BmpStreamClear;
    {清空原來位圖流}
    BmpStreamWriteBuffer(Count Sizeof(Count));
    {將原來位圖的大小保存到新的位圖流中以便使用}
    BmpStreamCopyFrom(DestStream );
    {將壓縮數據附加到新的位圖流後面}
    BmpStreamPosition := ;
    NMStrmPostIt(BmpStream);
    {發送位圖流}
    finally
    DestStreamFree;
    BmpStreamDestroy ;
    BitMapDestroy;
    DeleteDC(SourceDC);
    ReleaseDC(BhandleSourceDC);
    end; 
    {釋放有關資源}
    End;

    該過程得到整個屏幕的圖象拷貝並利用壓縮流SourceStream和內存流 Deststream將位圖壓縮並重新把位圖大小和壓縮數據流保存到位圖流中發送出去發送位圖大小的目的是在解壓前來確定需要的內存空間

    procedure TServerFormNMStrmServMSG(Sender: TComponent;
    const sFrom: String; strm: TStream);
    Var
    StreamStrDestStream:TMemoryStream;
    SourceStream:TDecompressionStream;
    count:Integer;
    buffer:pointer;
    begin
    ScreenImagePictureBitmap:=nil;
    If Strm Is TMemoryStream Then
    StreamStr := Strm AS TMemoryStream
    Else
    Exit;
    StreamStrPosition := ;
    StreamStrReadBuffer(Count Sizeof(Count));
    {得到位圖的大小}
    GetMem(BufferCount);
    {申請數據空間}
    DestStream := TMemoryStreamCreate;
    SourceStream := TDecompressionStreamCreate(StreamStr);
    {構建解壓流壓縮數據由StreamStr 流得到}
    StatusBarSimpleText := 正在處理圖象;
    Try
    SourceStreamReadBuffer(Buffer^Count);
    {讀出解壓數據}
    DestStreamWriteBuffer(Buffer^Count);
    {保存到位圖流中}
    DestStreamPosition := ;
    ScreenImagePictureBitmapLoadFromStream(DestStream);
    {顯示到屏幕上}
    Finally
    FreeMem(Buffer);
    DestStreamDestroy;
    SourceStreamDestroy;
    End;
    end;
  
    該過程首先從得到的數據流中取得位圖大小並申請內存空間然後建立解壓流並將解壓數據保存到位圖流中然後顯示到屏幕上


From:http://tw.wingwit.com/Article/program/Delphi/201311/24717.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.