線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3734
推到 Plurk!
推到 Facebook!

有關字串壓縮 及 解壓縮 的問題 ??

答題得分者是:pcboy
小蚊子
中階會員


發表:55
回覆:267
積分:94
註冊:2002-06-08

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-02-03 11:20:29 IP:210.66.xxx.xxx 訂閱
    有一文字字串(不是檔案),想用類似 zip 壓縮方式把它 空間縮小,不知有函數可以處理  ?? 當然也要有解壓縮的功能

例 : sKK1 字串,長度是 3000 個 byte , 壓完後 sKK2 字串,長度 小於 3000 個 byte ;
sKK1, 及 sKK2 都是字串型態


var
sKK1 , sKK2 : string;

begin

sKK2 := zip_Process( sKK1);

Result := sKK2;
end;


謝謝您

pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-02-03 15:40:06 IP:203.204.xxx.xxx 未訂閱
關於 Delphi 中壓縮流和解壓流的應用
作者:馮志強 來源:賽迪網社區 發佈時間:2006.04.06

軟體發展者不免都要遇到壓縮資料的問題!經常使用Delphi的朋友都知道,它為我們提供了兩個流類(TCompressionStream和TDecompressionStream)來完成資料的壓縮和解壓縮,但美中不足的是,該流在Delphi 的幫助中沒有詳細的說明,使得它們在使用起來有一定得困難。其實在Delphi系統中提供了這兩個類的源代碼和庫。保存在Delphi 光碟的\Info\Extras\Zlib\ Src和\Info\Extras\Zlib\Obj目錄中(其中OBJ目錄中保存的是庫,Src目錄中保存的是源代碼,感興趣的朋友可以看看)。本人在使用的過程中,對它們有了一定的瞭解。
一、 類的說明
1、 基類 TCustomZlibStream:類TCustomZlibStream 是類TCompressionStream和TDecompressionStream 類的基類,它主要有一個屬性: "2"> Procedure "2">2、 壓縮類TCompressionStream:類TCompressionStream除了繼承了基類的 "2"> 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的配合使用,我們可以非常方便地完成資料的壓縮和解壓,下面就是本人在編寫螢幕拷貝程式中的使用例子:
<textarea class="delphi" rows="10" cols="60" name="code">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; </textarea>
該過程得到整個螢幕的圖像拷貝,並利用壓縮流SourceStream和記憶體流 Deststream將點陣圖壓縮,並重新把點陣圖大小和壓縮資料流程保存到點陣圖流中,發送出去,發送點陣圖大小的目的是在解壓前來確定需要的記憶體空間。
<textarea class="delphi" rows="10" cols="60" name="code">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; </textarea>
該過程首先從得到的資料流程中取得點陣圖大小,並申請記憶體空間,然後建立解壓流,並將解壓資料保存到點陣圖流中,然後顯示到螢幕上。
本文程式在Delphi6.0中調試通過
http://tech.ccidnet.com/art/1079/20060405/498319_1.html
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
boson
中階會員


發表:71
回覆:154
積分:85
註冊:2004-07-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-02-04 10:24:06 IP:218.170.xxx.xxx 訂閱
我買過兩家的壓縮元件, 都不錯
1. ZipTV (http://www.ziptv.com)
2. TCompress (http://www.spis.co.nz/compress.htm)

ZipTV 相當強大, 但主要以壓縮檔案為主, 現在的版本提供也字串壓縮,
TCompress 主要是字串與 stream 壓縮 (也可以壓縮檔案)

如果你只是要在記憶體內壓縮 string, 則 TCompress 使用上比較方便,
但 ZipTV 蠻便宜的, 且功能強大, 支援所有常見的壓縮演算法, 因此我比較建議買 ZipTV


pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-02-06 11:02:49 IP:61.219.xxx.xxx 未訂閱
這裡有含  Source Code 的範例

http://www.torry.net/pages.php?id=357
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
系統時間:2017-12-14 23:07:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!