title: Clear a TBitmap before changing it in Delphi (VCL/Windows)
body: <p>This is about Delphi, 32 bits and Windows/VCL:</p>
  
  <p>For a procedure that takes an input bitmap and writes to an output bitmap with a given format (PixelFormat: pf8Bit with a gray scale palette) I use the following code:</p>
  
  <pre><code>procedure ConvertBitmap(_inBmp: TBitmap; _outBmp: TBitmap);
  begin
    _outBmp.PixelFormat := pf8Bit;
    _outBmp.Palette := MakeGrayPalette();
    _outBmp.SetSize(_inBmp.Width, _inBmp.Height);
    // code that works on ScanLines goes here
  end;
  </code></pre>
  
  <p>The Output bitmap might not be empty when it is being passed to this procedure, but might contain anything in any format. It will be completely overwritten in the procedure.</p>
  
  <p>I wonder whether simply changing its PixelFormat might create some overhead (e.g. convert the old content to the new pixel format), so should I somehow clear it first, e.g. by calling _outBmp.SetSize(0, 0) or any other means? If yes, what would be the most efficient way?</p>
  
  <p>EDIT:</p>
  
  <p>I just did some timing with this code:</p>
  
  <pre><code>procedure TimingTest;
  var
    Stopwatch1: TStopwatch;
    Stopwatch2: TStopwatch;
    bmp: TBitmap;
    i: Integer;
  begin
    bmp := TBitmap.Create;
    try
      Stopwatch1 := TStopwatch.Create;
      Stopwatch2 := TStopwatch.Create;
      for i := 0 to 10 - 1 do begin
        bmp.PixelFormat := pf24bit;
        bmp.SetSize(16 * 1024, 8 * 1024);
        Stopwatch1.Start;
        bmp.PixelFormat := pf8bit;
        bmp.Palette := MakeGrayPalette();
        Stopwatch1.Stop;
      end;
      for i := 0 to 10 - 1 do begin
        bmp.PixelFormat := pf24bit;
        bmp.SetSize(16 * 1024, 8 * 1024);
        Stopwatch2.Start;
        bmp.SetSize(0, 0);
        bmp.PixelFormat := pf8bit;
        bmp.Palette := MakeGrayPalette();
        Stopwatch2.Stop;
      end;
      l_Timing.Caption := Format('%.3f [s] vs %.3f [s]', [
      Stopwatch1.ElapsedMilliseconds / 1000, Stopwatch2.ElapsedMilliseconds / 1000]);
    finally
      FreeAndNil(bmp);
    end;
  end;
  </code></pre>
  
  <p>The result on my computer (which is not slow):
  5.331 [s] vs. 0.322 [s]</p>
  
  <p>Unless I made an implementation error, this is quite significant. This is admittedly with a rather large bitmap though, but even with a more resonable size of 4096x4096 I get 0.693 vs. 0.040 which is still significant if this operation is executed many times (which it will be: several million times in fact).</p>
  
  <p>This answers the question of whether there is a performance impact with a clear yes.</p>
  
  <p>The remaining question is: Is SetSize(0,0) the most efficient way to clear a bitmap or is there a better way?</p>
  
  <p>EDIT2:</p>
  
  <p>TBitmap.Assign(nil) is another way to clear the bitmap:</p>
  
  <pre><code>    for i := 0 to 10 - 1 do begin
        bmp.PixelFormat := pf24bit;
        bmp.SetSize(16 * 1024, 8 * 1024);
        Stopwatch3.Start;
        bmp.Assign(nil);
        bmp.PixelFormat := pf8bit;
        bmp.Palette := MakeGrayPalette();
        Stopwatch3.Stop;
      end;
  </code></pre>
  
  <p>The timing is similar to .SetSize(0, 0).</p>