Search code examples
delphidrawdelphi-10-seattletcanvas

My code with TGraphic.Draw(Canvas, Rect) does not work


In Delphi 10 Seattle, I need to insert an image into an ImageList. The image is in a descendant of TGraphicControl (see source code below). The insertion seems to work. However, I get only a white rectangle in the ImageList:

function InsertCloudImageIntoImageList(AdvCloudImage1: TAdvCloudImage): Integer;
// TAdvCloudImage = class(TGraphicControl)
// WebPicture is TCloudPicture = class(TGraphic)
var
  TempBitmap: TBitmap;
  R: TRect;
begin
  Result := 0;
  TempBitmap := TBitmap.Create;
  try
    TempBitmap.SetSize(16, 16);
    R.Width  := 16;
    R.Height := 16;
    R.Top := 0;
    R.Left := 0;

    AdvCloudImage1.WebPicture.Draw(TempBitmap.Canvas, R);
    Result := Form1.ImageList1.Add(TempBitmap, nil);
  finally
    TempBitmap.Free;
  end;
end;

I suspect the bug is in the drawing on the bitmap canvas?


Solution

  • The correct way to draw here is to call Draw on the destination bitmap's canvas, passing the source graphic. The method you call is declared protected in TGraphic which indicates that you are not meant to call it from consumer code.

    So instead of

    AdvCloudImage1.WebPicture.Draw(TempBitmap.Canvas, R);
    

    You should use

    TempBitmap.Canvas.Draw(0, 0, AdvCloudImage1.WebPicture);
    

    This greatly simplifies the function since you no longer need the TRect variable. Furthermore, there's no point assigning to Result more than once. The entire function can be:

    function InsertCloudImageIntoImageList(AdvCloudImage1: TAdvCloudImage): Integer;
    var
      TempBitmap: TBitmap;
    begin
      TempBitmap := TBitmap.Create;
      try
        TempBitmap.SetSize(16, 16);
        TempBitmap.Canvas.Draw(0, 0, AdvCloudImage1.WebPicture);
        Result := Form1.ImageList1.Add(TempBitmap, nil);
      finally
        TempBitmap.Free;
      end;
    end;