流有点大
影响数据传输 问问流可以压缩吗
如果可以流怎么压缩
最好给个例子
解决方案 »
- 如何访问Package中的全局变量?大虾进来。。。
- 简单的并发控制问题,不看白不看!
- 当图片比image大的时候,如何将图片按比例全部显示在image框中?
- 请各位给予帮助
- [急!!]如何知道DBGrid中和记录数?
- 求助!谁能给个Delphi5下的ADO补丁下载地址?
- 请问:如何将文字存入二进制文件
- 奇女!奇女!奇女!中华之绝观,不看不知道,一看吓一跳,令诸位男程序员汗颜的才女,不看别后悔啊!!!!!!!!!!!!!!
- 求控件:TBitBtn、TSpeedButton的图像能放在dll里面
- 我想在屏幕上模拟一个鼠标按键,请问postmessage函数该怎么写?
- sql语句如何用adoquery控件把统计表中的记录数赋值给变量xmbh_sum在线等待。来者有分
- fastreport问题?
软件开发者不免都要遇到压缩数据的问题!经常使用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(压缩类型),它由如下几个定义: ①、 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 事件。
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; 该过程首先从得到的数据流中取得位图大小,并申请内存空间,然后建立解压流,并将解压数据保存到位图流中,然后显示到屏幕上。
标题:流的压缩和解压
说明:适用文件压缩、图象压缩等;调用ZLib单元的方法实现
设计:Zswang
支持:[email protected]
日期:2004-03-24
//*)(*//============================================================================
设计思路:
创建TCompressionStream、TDecompressionStream实例进行压缩和解压
============================================================================//*)uses ZLib;const cBufferSize = $4096;function StreamCompression(mInputStream: TStream; mOutputStream: TStream): Integer;
var
I: Integer;
vBuffer: array[0..cBufferSize]of Char;
begin
Result := -1;
if not (Assigned(mInputStream) and Assigned(mOutputStream)) then Exit;
with TCompressionStream.Create(clMax, mOutputStream) do try
for I := 1 to mInputStream.Size div cBufferSize do begin
mInputStream.Read(vBuffer, cBufferSize);
Write(vBuffer, cBufferSize);
end;
I := mInputStream.Size mod cBufferSize;
if I > 0 then begin
mInputStream.Read(vBuffer, I);
Write(vBuffer, I);
end;
finally
Free;
end;
end; { StreamCompression }function StreamDecompression(mInputStream: TStream; mOutputStream: TStream): Integer;
var
vBuffer: array[0..cBufferSize]of Char;
I: Integer;
begin
Result := -1;
if not (Assigned(mInputStream) and Assigned(mOutputStream)) then Exit;
with TDecompressionStream.Create(mInputStream) do try
repeat
I := Read(vBuffer, cBufferSize);
mOutputStream.Write(vBuffer, I);
until I = 0;
Result := mOutputStream.Size;
finally
Free;
end;
end; { StreamDecompression }//Example
procedure TForm1.Button1Click(Sender: TObject);
var
vInputStream: TFileStream;
vOutputStream: TFileStream;
begin
vInputStream := TFileStream.Create('c:\temp\temp.exe', fmOpenRead);
vOutputStream := TFileStream.Create('c:\temp\temp.exe.z', fmCreate);
try
StreamCompression(vInputStream, vOutputStream);
finally
vInputStream.Free;
vOutputStream.Free;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
var
vInputStream: TFileStream;
vOutputStream: TFileStream;
begin
vInputStream := TFileStream.Create('c:\temp\temp.exe.z', fmOpenRead);
vOutputStream := TFileStream.Create('c:\temp\temp~.exe', fmCreate);
try
StreamDecompression(vInputStream, vOutputStream);
finally
vInputStream.Free;
vOutputStream.Free;
end;
end;