Save canvas as an image

delphi, delphi-xe2

Solution

At the moment you most likely have code in an `OnPaint` event for a `TPaintBox` or the form itself. That code might look like this:

procedure TMyForm.PaintBox1Paint(Sender: TObject);
begin
  with PaintBox1.Canvas do
  begin
    MoveTo(0, 0);
    LineTo(42, 666);
    // and so on.
  end;
end;

We need to do a little re-factoring. We need to extract that paint code into a separate method. Pass that method a canvas so that it is agnostic of the canvas on which it draws.

procedure TMyForm.PaintToCanvas(Canvas: TCanvas);
begin
  with Canvas do
  begin
    MoveTo(0, 0);
    LineTo(42, 666);
    // and so on.
  end;
end;

procedure TMyForm.PaintBox1Paint(Sender: TObject);
begin
  PaintToCanvas(PaintBox1.Canvas);
end;

We are now back exactly where we started, but ready to strike at the real goal. Let's write a function to paint to a bitmap and then save to a file:

procedure TMyForm.PaintToFile(const FileName: string);
var
  Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.SetSize(Paintbox1.Width, Paintbox1.Height);
    PaintToCanvas(Bitmap.Canvas);
    Bitmap.SaveToFile(FileName);
  finally
    Bitmap.Free;
  end;
end;

This can naturally be extended to other image types like GIF, PNG, JPEG etc.

Problem

I am writing a program using Delphi XE2. I draw some lines and shapes on a Canvas. I want to save that Canvas as an image file using a save dialog. So I have a save button on my form and by clicking it, it opens the save dialog. How should I proceed to be able to save the Canvas?

Original source