delphi数据压缩处理(1)
borland公司推出的 rad开发工具 delphi 5.0作为 windows平台上的主流开发工具,其可视化的开发环境和面向对象编程的强大功能已经吸引了无数的开发人员。但是,一些程序员在实际的开发过程中却时常为对大量的数据进行压缩而伤透脑筋,不得不去查找一些高效的压缩算法或在网上查找第三方的控件来实现压缩。难道 delphi本身没有提供这个功能吗?其实 delphi的程序设计师早就考虑到了这一点,他们提供了 zlib.pas和 zlibconst.pas两个单元文件来解决数据压缩问题,实现了很高的数据压缩比率。这两个文件保存在 delphi 5.0安装光盘上 \info\extras\zlib目录下,此外,在 info\extras\zlib\obj目录中还保存了 zlib.pas单元引用的 obj文件。下面本文以压缩一个屏幕拷贝为例介绍如何使用这项功能。
解决思路
首先利用屏幕拷贝捕捉到当前整个屏幕的图像,然后在内存中保存为 bmp文件格式。压缩时,使用 tcompressionstream对象对原始图像进行压缩并且保存为自定义的文件格式;解压缩时,使用 tdecompressionstream对象对被压缩的图像进行解压缩,还原为 bmp格式的图像文件。
具体实现
新建一个项目文件,在主单元的接口部分引用 zlib.pas,在主表单上放置两个按钮 button1、 button2,在它们的 onclick事件中写上相应的过程调用代码。
部分程序源代码如下:
unit unit1;
interface
uses
windows, messages, sysutils, classes, graphics, controls, forms, dialogs,stdctrls, zlib;
type
tform1 = class(tform)
button1: tbutton;
button2: tbutton;
procedure button1click(sender: tobject);
procedure button2click(sender: tobject);
private
{ private declarations }
public
{ public declarations }
end;
var
form1: tform1;
implementation
{$ r* .dfm}
1.捕捉全屏幕图像
procedure getscreen(var bmp: tbitmap);
var
dc: hdc;
mycanvas: tcanvas;
myrect: trect;
begin
dc := getwindowdc(0);
mycanvas := tcanvas.create;
try
mycanvas.handle := dc;
myrect:=rect(0, 0,screen.width, screen.height);
file://图像为 24位真彩色,也可根据实际需要调整
bmp.pixelformat := pf24bit;
bmp.width := myrect.right;
bmp.height := myrect.bottom;
file://捕捉整个屏幕图像
bmp.canvas.copyrect(myrect, mycanvas, myrect);
finally
mycanvas.handle := 0;
mycanvas.free;
releasedc(0, dc);
end;
end;
2.压缩图像
procedure compressbitmap(var compressedstream: tmemorystream;const compressionlevel: tcompressionlevel);
var
sourcestream: tcompressionstream;
deststream: tmemorystream;
count: integer;
begin
file://获得图像流的原始尺寸
count := compressedstream.size;
deststream := tmemorystream.create;
sourcestream:=tcompressionstream.create
(compressionlevel, deststream);
try
file://sourcestream中保存着原始的图像流
compressedstream.savetostream(sourcestream);
file://将原始图像流进行压缩, deststream中保存着压缩后的图像流
sourcestream.free;
compressedstream.clear;
file://写入原始图像的尺寸
compressedstream.writebuffer(count, sizeof
(count));
file://写入经过压缩的图像流
compressedstream.copyfrom(deststream, 0);
finally
deststream.free;
end;
end;
3.还原被压缩图像
procedure uncompressbitmap(const compressedstream: tfilestream; var bmp: tbitmap);
var
sourcestream: tdecompressionstream;
deststream: tmemorystream;