delphifiremonkeydelphi-xe4

VCL.Bitmap To FMX.Bitmap


I found the this code on the web, but FMX.Bitmap does not have a scanline. Is it possible to copy or draw a VCL.TBitmap to a FMX.Bitmap somehow?

{$IFDEF MSWINDOWS}
type
  TBitmap = FMX.Types.TBitmap;
  TVclBitmap = Vcl.Graphics.TBitmap;

procedure TakeScreenshot(Dest: FMX.Types.TBitmap);
var
  DC: HDC;
  Size: TPointF;
  VCLBitmap: TVclBitmap;
  Y: Integer;
begin
  VCLBitmap := nil;
  //Size := FMX.Platform.IFMXScreenService.GetScreenSize;
  DC := GetDC(0);
  try
    VCLBitmap := TVclBitmap.Create;
    VCLBitmap.PixelFormat := pf32bit;
    VCLBitmap.SetSize(Trunc(Size.X), Trunc(Size.Y));
    BitBlt(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height,
      DC, 0, 0, SRCCOPY);
    Dest.SetSize(VCLBitmap.Width, VCLBitmap.Height);
    { The format of a FMX bitmap and a 32 bit VCL bitmap is the same, so just
      copy the scanlines. - not true- FMX bitmap does not have ScanLine? }
    for Y := Dest.Height - 1 downto 0 do
      Move(VCLBitmap.ScanLine[Y]^, Dest.ScanLine[Y]^, Dest.Width * 4);
    {Dest.Canvas.DrawBitmap(); Not possible to assign or draw}
  finally
    ReleaseDC(0, DC);
    VCLBitmap.Free;
  end;
end;
{$ENDIF}

Solution

  • You can use Stream :

    {$IFDEF MSWINDOWS}
    
    type
    
      TVclBitmap = Vcl.Graphics.TBitmap;
    
    procedure TakeScreenshot(Dest: TBitmap);
    var
      DC: HDC;
      Size: TPointF;
      VCLBitmap: TVclBitmap;
      Y: Integer;
      MS: TMemoryStream;
    begin
      MS := TMemoryStream.Create;
      VCLBitmap := nil;
      // Size := FMX.Platform.IFMXScreenService.GetScreenSize;
      DC := GetDC(0);
      Size.X := 500;
      Size.Y := 500;
      try
        VCLBitmap := TVclBitmap.Create;
        VCLBitmap.PixelFormat := pf32bit;
        VCLBitmap.SetSize(Trunc(Size.X), Trunc(Size.Y));
        BitBlt(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, DC,
          0, 0, SRCCOPY);
        Dest.SetSize(VCLBitmap.Width, VCLBitmap.Height);
        { The format of a FMX bitmap and a 32 bit VCL bitmap is the same, so just
          copy the scanlines. - not true- FMX bitmap does not have ScanLine? }
        VCLBitmap.SaveToStream(MS);
        MS.Position := 0;
        Dest.LoadFromStream(MS);
        MS.Free;
        { Dest.Canvas.DrawBitmap(); Not possible to assign or draw }
      finally
        ReleaseDC(0, DC);
        VCLBitmap.Free;
      end;
    end;
    {$ENDIF}