--- ---
Question
Does anybody know whether it is possible to write some small TBitmaps with different widths and heights into one file?

Saving the TBitmap to a stream, and appending other TBitmaps to that stream, then saving the stream to disk would be the method.

    procedure SaveBitmapToStream(aBitmap: TBitmap; aStream: TStream);
    var
      ms: TMemoryStream;
      size: Integer;
    begin
      Assert(Assigned(aBitmap));
      Assert(Assigned(aStream));
      ms:= TMemoryStream.Create;
      try
        aBitmap.SaveToStream(ms);
        ms.position := 0;
        size := ms.Size;
        aStream.WriteBuffer(size, Sizeof(size));
        aStream.CopyFrom(ms, size);
      finally
        ms.free
      end;
    end;

then

    aStream.SaveToFile('FileName');

To read then first off do:

    aStream.LoadFromFile('FileName');

then

    procedure LoadBitmapFromStream(aBitmap: TBitmap; aStream: TStream);
    var
      ms: TMemoryStream;
      size: Integer;
    begin
      Assert(Assigned(aBitmap));
      Assert(Assigned(aStream));
      ms:= TMemoryStream.Create;
      try
        aStream.ReadBuffer(size, Sizeof(size));
        ms.CopyFrom(aStream, size);
        ms.position := 0;
        aBitmap.LoadfromStream(ms);
      finally
        ms.free
      end;
    end;

## Demo code

A ready made project containing this demo code is available. View the project.

This demo shows how to implement this tip. We will load two bitmaps into two image controls. Clicking a button will store those two bitmaps in a single file. A click on a second button will load the file, separate the bitmaps and display them in a second pair of image controls.

Start a new Delphi VCL application then proceed as follows:

- Drop four image controls on the form. Load sample bitmaps into Image1 and Image2. Leave Image3 and Image4 empty.
- Drop two TButtons onto the form and create an OnClick event handler for each button.
- Name the form "Form1" and save the form unit as `Unit1.pas`.
- Now code Unit1 as follows:

    unit Unit1;

    interface

    uses
      SysUtils, Forms, Controls, StdCtrls, Graphics, Classes, ExtCtrls;

    type
      TForm1 = class(TForm)
        Image1: TImage;
        Image2: TImage;
        Image3: TImage;
        Image4: TImage;
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    const
      // test file name: change and/or provide a path if required
      cFileName = 'test';

    procedure SaveBitmapToStream( aBitmap: TBitmap; aStream: TStream );
    var
      ms: TMemoryStream;
      size: Integer;
    begin
      Assert( Assigned(aBitmap));
      Assert( Assigned(aStream));
      ms:= TMemoryStream.Create;
      try
        aBitmap.SaveToStream(ms);
        ms.position := 0;
        size := ms.Size;
        aStream.WriteBuffer( size, Sizeof(size));
        aStream.CopyFrom(ms, size );
      finally
        ms.free
      end;
    end;

    procedure LoadBitmapFromStream(aBitmap: TBitmap; aStream: TStream );
    var
      ms: TMemoryStream;
      size: Integer;
    begin
      Assert( Assigned(aBitmap));
      Assert( Assigned(aStream));
      ms:= TMemoryStream.Create;
      try
        aStream.ReadBuffer( size, Sizeof(size));
        ms.CopyFrom(aStream, size );
        ms.position := 0;
        aBitmap.LoadfromStream(ms);
      finally
        ms.free
      end;
    end;

    { TForm1 }

    procedure TForm1.Button1Click(Sender: TObject);
    var
      FS: TFileStream;
    begin
      // Save Image1 and Image2 to single file
      FS := TFileStream.Create(cFileName, fmCreate);
      try
        SaveBitmapToStream(Image1.Picture.Bitmap, FS);
        SaveBitmapToStream(Image2.Picture.Bitmap, FS);
      finally
        FS.Free;
      end;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    var
      FS: TFileStream;
    begin
      // Load file, split up bitmaps and load into Image3 and Image4
      FS := TFileStream.Create(cFileName, fmOpenRead or fmShareDenyNone);
      try
        LoadBitmapFromStream(Image3.Picture.Bitmap, FS);
        LoadBitmapFromStream(Image4.Picture.Bitmap, FS);
      finally
        FS.Free;
      end;
    end;

    end.

Run the application and click Button1 to save the images to file. The file is named `test` and is stored in the demo executable's directory. If you don't have write access to the directory change the source to use a different directory. Click Button2 to read the file. The images should appear in the two empty image controls.

Demo by Peter Johnson