【转】[Delphi]使用TMemoryStream保存多张图片到文件,并读取

本文介绍如何利用Delphi中的TMemoryStream组件来保存多个图片到一个文件,并能够再次从该文件中读取并显示这些图片。通过定义THeader结构体来记录图像标识和大小,确保了图片数据的准确保存与读取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在百度知道待解决问题中找到的一题。提问者要求将多张图片保存到一个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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值