全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1102
推到 Plurk!
推到 Facebook!

什么是压缩?

尚未結案
clarky
一般會員


發表:14
回覆:22
積分:7
註冊:2003-04-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-15 15:16:34 IP:211.162.xxx.xxx 未訂閱
我想在编写程序时,涉及到备份时,都会作个压缩包,来保存备份资料。 那么,压缩的原理是怎样的,一个简单的压缩过程如何实现呢。我希望得到各位 先生的帮助。
kunying
一般會員


發表:17
回覆:28
積分:19
註冊:2002-03-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-16 03:32:47 IP:211.74.xxx.xxx 未訂閱
轉貼一篇文章給您參考,希望對您有幫助 http://www.yesky.com/20030311/1656296.shtml Delphi 中壓縮流和解壓流的應用 2003-03-11· ·馮志強··yesky 軟件開發者不免都要遇到壓縮數據的問題!經常使用Delphi的朋友都知道,它為我們提供了兩個流類(TCompressionStream和TDecompressionStream)來完成數據的壓縮和解壓縮,但美中不足的是,該流在Delphi 的幫助中沒有詳細的說明,使得它們在使用起來有一定得困難。其實在Delphi系統中提供了這兩個類的源代碼和庫。保存在Delphi 光盤的\Info\Extras\Zlib\ Src和\Info\Extras\Zlib\Obj目錄中(其中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(壓縮類型),它由如下幾個定義: 1、 clNone :不進行數據壓縮; 2、 clFastest:進行快速壓縮,犧牲壓縮效率; 3、 clDefault:進行正常壓縮; 4、 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; 該過程得到整個屏幕的圖像拷貝,並利用壓縮流SourceStream和內存流 Deststream將位圖壓縮,並重新把位圖大小和壓縮數據流保存到位圖流中,發送出去,發送位圖大小的目的是在解壓前來確定需要的內存空間。 procedure TServerForm.NMStrmServMSG(Sender: TComponent; const sFrom: String; strm: TStream); Var StreamStr,DestStream:TMemoryStream; SourceStream:TDecompressionStream; count:Integer; buffer:pointer; begin ScreenImage.Picture.Bitmap:=nil; If Strm Is TMemoryStream Then StreamStr := Strm AS TMemoryStream Else Exit; StreamStr.Position := 0; StreamStr.ReadBuffer(Count, Sizeof(Count)); {得到位圖的大小} GetMem(Buffer,Count); {申請數據空間} DestStream := TMemoryStream.Create; SourceStream := TDecompressionStream.Create(StreamStr); {構建解壓流,壓縮數據由StreamStr 流得到} StatusBar.SimpleText := '正在處理圖像'; Try SourceStream.ReadBuffer(Buffer^,Count); {讀出解壓數據} DestStream.WriteBuffer(Buffer^,Count); {保存到位圖流中} DestStream.Position := 0; ScreenImage.Picture.Bitmap.LoadFromStream(DestStream); {顯示到屏幕上} Finally FreeMem(Buffer); DestStream.Destroy; SourceStream.Destroy; End; end; 該過程首先從得到的數據流中取得位圖大小,並申請內存空間,然後建立解壓流,並將解壓數據保存到位圖流中,然後顯示到屏幕上。 本文程序在Delphi6.0中調試通過 ________________________ 「有時候你以為天要塌下來了,其實是因為你站歪了!」
------
________________________
「有時候你以為天要塌下來了,其實是因為你站歪了!」
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-16 07:38:05 IP:61.155.xxx.xxx 未訂閱
这儿有关于zlib压缩与解压缩的源码:    http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30226    供参考!!!    风花雪月 e梦情缘
------
风花雪月 e梦情缘
系統時間:2024-04-18 22:02:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!