本文整理自网络,侵删。
在百度知道待解决问题中找到的一题。提问者要求将多张图片保存到一个bat文件中,并可以在读取出来分别显示在TImage控件中。
借此好好温习了一下TMemoryStream的用法,并以此例贴上该类的使用方法:
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
//THeader:// 为了保存一个标志和需要保存的Image对象的size,方便在读取的时候作为Buffer大小读出// 还可以增加额外需要保存的信息// 在你的应用程序中使用这种结构,可以方便以后程序的扩展。type THeader = packed record Marker: array[0..5] of Char; Size: Integer; end;
type TForm1 = class(TForm) btnSave: TButton; Image1: TImage; Image2: TImage; Image3: TImage; Image4: TImage; btnLoad: TButton; procedure btnSaveClick(Sender: TObject); procedure btnLoadClick(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;const vFile = 'D:\Test.dat';implementation
{$R *.dfm}//保存按钮,为了测试,这里只用了2个Image
procedure TForm1.btnSaveClick(Sender: TObject);var sStream, sStream1: TMemoryStream; AHeader: THeader; procedure SaveBitmapToStream(vImage: TImage); begin sStream1.Clear; vImage.Picture.Bitmap.SaveToStream(sStream1); //准备头 ZeroMemory(@Aheader, SizeOf(THeader)); StrCopy(AHeader.Marker, PChar('Bitmap'));//将String字串保存到char数组中。 AHeader.Size := sStream1.Size; //写头 sStream.WriteBuffer(AHeader, SizeOf(THeader));
//WriteBuffer方法:将Buffer数据写到流中,第一位是要写的数据,第二位为内容长度 //保存image1 vImage.Picture.Bitmap.SaveToStream(sStream); end;begin sStream := TMemoryStream.Create; sStream1 := TMemoryStream.Create; sStream.Seek(0, soFromBeginning);
SaveBitmapToStream(Image1); SaveBitmapToStream(Image2);
sStream.SaveToFile(vFile); sStream1.Free; sStream.Free;end;
//读取图片// 因为要读2张分别放到不同的Timage中,所以使用的固定的读取。// 如果你的图片量大,可以采取循环读取的方式。
procedure TForm1.btnLoadClick(Sender: TObject);var sStream, sStream1: TMemoryStream; sHeader: THeader; imgList: TList; vBitmap: TBitmap; i: Integer;begin sStream := TMemoryStream.Create; sStream1 := TMemoryStream.Create; imgList := TList.create; sStream.LoadFromFile(vFile); sStream.Position := 0;
while sStream.Position < sStream.Size do/
//遍历这个流文件,直到最后读完。
//Position不需要手动加,使用ReadBuffer方法会自动指到当前读的位置 begin ZeroMemory(@sheader, SizeOf(THeader)); sStream.ReadBuffer(sHeader, SizeOf(THeader)); if sHeader.Size > 0 then begin sStream1.CopyFrom(sStream, sHeader.Size); vBitmap := TBitmap.Create; sStream1.Position := 0;//因为sStream1当前的位置已经指到最后,所以必须把位置设为0,才能正确读取出流数据。 vBitmap.LoadFromStream(sStream1); imgList.Add(vBitmap);//为了更好的通用性,将读取的图片放到一个TList中,这样可以不受2个图片的固定限制。 end; sStream1.Clear; end;
if imgList.Count >= 2 then begin Image3.Picture.Bitmap := TBitmap(imgList[0]); Image4.Picture.Bitmap := TBitmap(imgList[1]); end;
sStream.Free; sStream1.Free; for i := 0 to imgList.Count - 1 do TBitmap(imgList[i]).Free; imgList.Free;end;
end.
相关阅读 >>
Delphi xe10 手机内部系统相关操作(手机信息、震动、剪贴板、键盘、电话、拨号)
更多相关阅读请进入《Delphi》频道 >>