Delphi 5 安裝盤 \Info\Extras\Zlib 目錄提供 Zlib.pas、ZlibConst.pas 及 .obj 文件,封裝了 zlib 1.1.3 庫,提供 TCompressionStream/TDecompressionStream 類,可輕鬆實現高壓縮比的數據壓縮,無需第三方組件。
| 類 | 關鍵構造/屬性/事件 |
|---|---|
TCompressionStream | Create(CompressionLevel: TCompressionLevel; Dest: TStream)、CompressionRate (只讀,壓縮比)、OnProgress (進度回調) |
TDecompressionStream | Create(Source: TStream)、OnProgress |
TCompressionLevel | clNone, clFastest, clDefault, clMax (0~9 級) |
procedure GetScreen(var Bmp: TBitmap);
var DC: HDC; Canvas: TCanvas; Rect: TRect;
begin
DC := GetWindowDC(0); // 桌面 DC
Canvas := TCanvas.Create;
try
Canvas.Handle := DC;
Rect := Rect(0, 0, Screen.Width, Screen.Height);
Bmp.PixelFormat := pf24bit; // 24 位真彩色
Bmp.Width := Rect.Right; Bmp.Height := Rect.Bottom;
Bmp.Canvas.CopyRect(Rect, Canvas, Rect); // BitBlt 複製
finally
Canvas.Handle := 0; Canvas.Free; ReleaseDC(0, DC);
end;
end;
procedure CompressBitmap(var CompressedStream: TMemoryStream; Level: TCompressionLevel = clDefault);
var SourceStream: TCompressionStream; DestStream: TMemoryStream; OrigSize: Integer;
begin
OrigSize := CompressedStream.Size; // 原始 BMP 流大小
DestStream := TMemoryStream.Create;
try
SourceStream := TCompressionStream.Create(Level, DestStream);
try
CompressedStream.SaveToStream(SourceStream); // 寫入壓縮流
finally SourceStream.Free; end; // 必須 Free 才會刷新 zlib 尾部校驗和
CompressedStream.Clear;
CompressedStream.WriteBuffer(OrigSize, SizeOf(OrigSize)); // 寫入原始大小 (解壓需知)
CompressedStream.CopyFrom(DestStream, 0); // 追加壓縮數據
finally DestStream.Free; end;
end;
procedure UnCompressBitmap(const CompressedStream: TFileStream; var Bmp: TBitmap);
var SourceStream: TDecompressionStream; DestStream: TMemoryStream; Buffer: PChar; OrigSize: Integer;
begin
CompressedStream.ReadBuffer(OrigSize, SizeOf(OrigSize)); // 讀取原始大小
GetMem(Buffer, OrigSize);
DestStream := TMemoryStream.Create;
try
SourceStream := TDecompressionStream.Create(CompressedStream);
try
SourceStream.ReadBuffer(Buffer^, OrigSize); // 解壓到緩衝區
finally SourceStream.Free; end;
DestStream.WriteBuffer(Buffer^, OrigSize); // 寫入目標流
DestStream.Position := 0;
Bmp.LoadFromStream(DestStream); // 還原 BMP
finally FreeMem(Buffer); DestStream.Free; end;
end;
procedure TForm1.Button1Click(Sender: TObject); // 壓縮按鈕
var Bmp: TBitmap; CompressedStream: TMemoryStream;
begin
Bmp := TBitmap.Create; CompressedStream := TMemoryStream.Create;
try
GetScreen(Bmp);
Bmp.SaveToStream(CompressedStream); // BMP -> 內存流
CompressBitmap(CompressedStream, clDefault);
CompressedStream.SaveToFile('C:\cj.dat'); // 自定義壓縮文件
finally Bmp.Free; CompressedStream.Free; end;
end;
procedure TForm1.Button2Click(Sender: TObject); // 解壓按鈕
var Bmp: TBitmap; CompressedStream: TFileStream;
begin
Bmp := TBitmap.Create;
CompressedStream := TFileStream.Create('C:\cj.dat', fmOpenRead);
try
UnCompressBitmap(CompressedStream, Bmp);
Bmp.SaveToFile('C:\cj.bmp'); // 還原 BMP 文件
finally Bmp.Free; CompressedStream.Free; end;
end;
// 壓縮時顯示比率
procedure TForm1.CompressBitmap(...);
var SourceStream: TCompressionStream; ...
begin
...
SourceStream := TCompressionStream.Create(Level, DestStream);
SourceStream.OnProgress := CompressionProgress; // 綁定進度事件
...
// 壓縮完成後讀取比率
Label1.Caption := Format('壓縮比: %.2f%%', [SourceStream.CompressionRate * 100]);
end;
procedure TForm1.CompressionProgress(Sender: TObject; Position: Integer);
begin
ProgressBar1.Position := Position; // Position 為已處理字節數
Application.ProcessMessages;
end;
TCompressionStream.Free **必須**在讀取 CompressionRate 或 DestStream 數據前調用,否則 zlib 流未正確結束 (缺少 Adler-32 校驗和)。clFastest 平衡速度/比率。TBytesStream/TMemoryStream,避免字符串類型混淆。Delphi 內置 Zlib 單元提供了工業級壓縮能力。通過 TCompressionStream/TDecompressionStream 配合 TMemoryStream/TFileStream,僅需十幾行代碼即可實現「截圖 → 高壓縮存儲 → 完美還原」全流程。掌握流操作與自定義文件頭 (存原始長度) 是正確使用的關鍵。