请教大家一个问题:我想把一些图片,用FileStream变成二进制后,一个个字节地存入硬盘中,有两个要求1 是能高效地取出每张图片的字节码,然后重新还原出图片,,2 图片所在的介质,是可移植的,就是说,我把“图片库”文件COPY到另一台机子的程序中,程序就能用那个新的图片库了。我目前想到的,能不能把图片存入dll文件中,但dll中还原图片,不知速度怎么样。如果用access文件,一个个字节地取,可能花的时间很多的。SQL Server等就不现实了,因为把图片库移值到另一台机子上很不方便。请教各位,还有什么更好的解决方案呢?先谢谢了。
以下方案是对于图片不是很多, 一次全部读入的内存的情况下的代码比较好的方法是你构造自己的列表类, 这样类型安全, 如类声明的关键部分可以如下:type
TGraphicItem = class
private
FKey: String;
FGraphic: TGraphic;
public
property Key: String read FKey write FKey;
property Graphic: TGraphic read FGraphic write FGraphic;
procedure ReadFromStream(AStream: TStream);
procedure WriteToStream(AStream: TStream);
end; TGraphicList = class(TObjectList)
public
property Items[Index: Integer]: TGraphicItem read GetItem write SetItem; default;
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
procedure LoadFromFile(const AFileName: String);
procedure SaveToFile(const AFileName: String);
end;// LoadFromFile 实现如下所示
// 注意, 此处使用的是TFileStream, 不要使用TMemoryStream, 因为使用TMemoryStream
// 会浪费更多的内存空间
procedure TGraphicList.LoadFromFile(const AFileName: String);
var
tmpStream: TFileStream;
begin
tmpStream := TFileStream.Create(AFileName, fmOpenRead);
try
LoadFromStream(tmpStream);
finally
tmpStream.Free;
end;
end;// SaveToFile 的实现方法如下
procedure TGraphicList.SaveToFile(const AFileName: String);
var
tmpStream: TFileStream;
begin
tmpStream := TFileStream.Create(AFileName, fmCreate);
try
SaveToStream(tmpStream);
finally
tmpStream.Free;
end;
end;// SaveToStream 实现如下
procedure TGraphicList.SaveToStream(AStream: TStream);
var
i: Integer;
tmpCount: Integer;
begin
tmpCount := Count;
AStream.WriteBuffer(tmpCount, sizeof(tmpCount));
for i := 0 to tmpCount - 1 do
Items[i].WriteToStream(AStream);
end;// LoadFromStream 实现如下
procedure TGraphicList.LoadFromStream(AStream: TStream);
var
tmpCount: Integer;
i: Integer;
tmpItem: TGraphicItem;
begin
Clear; // 注意此处如果OwnsObjects属性为True时, 其自动释放了列表中的所有对象
// 如果OwnsObjects为False时, 则需要则需要在此句之前增加释放列表中的所有对象的代码
AStream.ReadBuffer(tmpCount, sizeof(tmpCount));
for i := tmpCount - 1 downto 0 do
begin
tmpItem := TGraphicItem.Create;
try
tmpItem.ReadFromStream(AStream);
Add(tmpItem);
except
tmpItem.Free;
raise;
end;
end;
end;对于图像的保存, 可以保存图象的二进制数据, 因为这样其数据量较小
对于TGraphicItem, 必须保存Key, 二进制数据, 图像类型的标识(此处, 我使用类名)
对于字符串的保存, 先保存长度, 再保存内容
对于二进制数据的保存, 也先保存其长度, 再保存内容字符串的写入和读取函数如下
procedure WriteStringToStream(AStream: TStream; const AValue: String);
var
iLen: Integer;
begin
iLen := length(AValue);
AStream.WriteBuffer(iLen, sizeof(iLen));
if iLen > 0 then
AStream.WriteBuffer(AValue[1], iLen);
end;function ReadStringFromStream(AStream: TStream): String;
var
iLen: Integer;
begin
AStream.ReadBuffer(iLen, sizeof(iLen));
SetLength(Result, iLen);
if iLen > 0 then
AStream.ReadBuffer(Result[1], iLen);
end;二进制数据的写入的读取函数如下
procedure WriteStreamToStream(AStream: TStream; sub: TMemoryStream);
var
iLen: Integer;
begin
iLen := sub.Size;
AStream.WriteBuffer(iLen, sizeof(iLen));
if iLen > 0 then
AStream.WriteBuffer(sub.Memory^, iLen);
end;procedure ReadStreamFromStream(AStream: TStream; sub: TMemoryStream);
var
iLen: Integer;
begin
AStream.ReadBuffer(iLen, sizeof(iLen));
sub.SetSize(iLen);
if iLen > 0 then
AStream.ReadBuffer(sub.Memory^, iLen);
end;对于各项的读取和写入, 实现如下
procedure TGraphicItem.WriteToStream(AStream: TStream);
var
sub: TMemoryStream;
begin
WriteStringToStream(AStream, FKey);
WriteStringToStream(AStream, FGraphic.ClassName);
sub := TMemoryStream.Create;
try
FGraphic.SaveToStream(sub);
WriteStreamToStream(AStream, sub);
finally
sub.free;
end;
end;procedure TGraphicItem.WriteToStream(AStream: TStream);
var
sub: TMemoryStream;
tmpClassName: String;
tmpClass: TGraphicClass;
begin
FKey := ReadStringFromStream(AStream);
tmpClassName := ReadStringFromStream(AStream);
tmpClass := TGraphicClass(GetClass(tmpClassName));
if tmpClass = nil then
raise Exception.Create('graphic type not support'); // 此处最好用你自己声明的异常 if Assigned(FGraphic) then
FreeAndNil(FGraphic); FGraphic := tmpClass.Create;
sub := TMemoryStream.Create;
try
ReadStreamFromStream(AStream, sub);
sub.Position := 0;
FGraphic.LoadFromStream(sub);
finally
sub.Free;
end;
end;至此OK, 你所需要的关键部分都已经给出来了