程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 關於 Delphi 中壓縮流和解壓流的應用

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

編輯:Delphi

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

一、 類的說明

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

   Procedure OnProgress (Sender: TObject); dynamic;

 

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

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

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

   Constructor TCompressionStream.Create (CompressionLevel: TCompressionLevel; Dest: TStream);

 

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

①、 clNone :不進行數據壓縮;

②、 clFastest:進行快速壓縮,犧牲壓縮效率;

③、 clDefault:進行正常壓縮;

④、 clMax: 進行最大化壓縮,犧牲速度;

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

  Function TCompressionStream.Write (const Buffer; Count: Longint): Longint;

其中:Buffer:需要壓縮的數據;

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

函數返回寫入流的字節數。

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

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

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

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

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

數據讀出函數,Buffer: 存數據緩沖區;

Count: 緩沖區的大小;

函數返回讀出的字節數。

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

二、 類的使用

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

Procedure TClientForm.GetScreen;
             Var
              SourceDC,DestDC:HDC;
              Bhandle:HBITMAP;
              BitMap:TBitMap;
              BmpStream,Deststream:TMemoryStream;
              SourceStream:TCompressionStream;
              Count:Integer;
             Begin
              SourceDC:=CreateDC(display,,,nil);
              {得到屏幕的 DC}
              DestDC:=CreateCompatibleDC(SourceDC);
              {建立臨時 DC}
              Bhandle:=CreateCompatibleBitmap(SourceDC,Screen.Width, Screen.Height);
              {建立位圖}
              SelectObject(DestDC,Bhandle);
              {選擇位圖DC}
              BitBlt(DestDC,0,0,Screen.Width, Screen.Height,SourceDC,0,0,SRCCOPY);
              {拷貝整個屏幕}
              BitMap:=TBitMap.Create;
              BitMap.Handle := Bhandle;
              {保存屏幕位圖到 BitMap中}
              BmpStream:=TMemoryStream.Create;
              BitMap.SaveToStream(BmpStream);
              {建立位圖數據的內存流}
              count:=BmpStream.Size;
              {保存位圖的大小}
              DestStream:=TMemoryStream.Create;
              {目標流,保存壓縮數據}
              SourceStream:=TCompressionStream.Create(clMax, DestStream);
              {構建壓縮流,采用最大化壓縮,並保存到目標流中}
              try
               BmpStream.SaveToStream(SourceStream);
                {壓縮位圖流}
               SourceStream.Free;
                {完成壓縮,釋放壓縮流}
               BmpStream.Clear;
                {清空原來位圖流}
               BmpStream.WriteBuffer(Count, Sizeof(Count));
                {將原來位圖的大小保存到新的位圖流中,以便使用}
               BmpStream.CopyFrom(DestStream, 0);
                {將壓縮數據附加到新的位圖流後面}
               BmpStream.Position := 0;
               NMStrm.PostIt(BmpStream);
                {發送位圖流}
              finally
               DestStream.Free;
               BmpStream.Destroy ;
               BitMap.Destroy;
               DeleteDC(SourceDC);
               ReleaseDC(Bhandle,SourceDC);
              end; 
             {釋放有關資源}
            End;

該過程得到整個屏幕的圖象拷貝,並利用

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved