2

I receive a bitmap via TCameraComponent.SampleBufferReady event. Then I need to crop the received image so that I get a, for instance, recangular image.

I calculate the necessary parameters in the following method:

procedure TPersonalF.SampleBufferReady(Sender: TObject;
  const ATime: TMediaTime);
var
  BMP: TBitmap;
  X, Y, W, H: Word;
begin
  Try
    BMP := TBitmap.Create;
    CameraComponent.SampleBufferToBitmap(BMP, true);
    if BMP.Width >= BMP.Height then //landscape
    begin
      W:=BMP.Height;
      H:=W;
      Y:=0;
      X:=trunc((BMP.Width-BMP.Height)/2);
    end
    else //portrait
    begin
      W:=BMP.Width;
      H:=W;
      X:=0;
      Y:=trunc((BMP.Height-BMP.Width)/2);
    end;
    CropBitmap(BMP, Image1.Bitmap, X,Y,W,H);
  Finally
    BMP.Free;
  End;
end; 

I found an answer by @RRUZ delphi-how-do-i-crop-a-bitmap-in-place, but it requires a VCL API handle and is uses a Windows GDI function:

procedure CropBitmap(InBitmap, OutBitMap: TBitmap; X, Y, W, H: Word);
  begin
    OutBitMap.PixelFormat := InBitmap.PixelFormat;
    OutBitMap.Width := W;
    OutBitMap.Height := H;
    BitBlt(OutBitMap.Canvas.Handle, 0, 0, W, H, InBitmap.Canvas.Handle, X,
      Y, SRCCOPY);
  end;

My project is using FMX, and I plan to port it to Android platform in the future. So I am expecting to get problems if I use handles. How can I solve this problem?

Community
  • 1
  • 1
asd-tm
  • 3,381
  • 2
  • 24
  • 41

1 Answers1

2

Assuming you can guarantee that InBitmap and OutBitMap exist (if not, you can handle error checking yourself)

procedure CropBitmap(InBitmap, OutBitMap: TBitmap; X, Y, W, H: Word);
var
  iRect : TRect;
begin
    OutBitMap.PixelFormat := InBitmap.PixelFormat;
    OutBitMap.Width := W;
    OutBitMap.Height := H;
    iRec.Left := 0;
    iRect.Top := 0;
    iRect.Width := W;
    iRect.Height := H;
    OutBitMap.CopyFromBitmap( InBitMap, iRect, 0, 0 );
end;

It is the same as the original but uses Firemonkey CopyFromBitmap which is similar to the Windows rather cryptically named BitBlt.

Dsm
  • 5,870
  • 20
  • 24
  • Thank you very much, @Dsm, it almost works, though it does not accept `OutBitMap.PixelFormat := InBitmap.PixelFormat;` as it is a read-only property. There are two overload methods named `CopyFromBitmap` and I saw only the first and it had a single parameter `(const Source:TBitmap)` so it did ton suit me. Thank you once again! – asd-tm Jul 01 '15 at 15:46
  • Sorry - I didn't check the PixelFormat property - I just cut and pasted from the original code :blush: – Dsm Jul 02 '15 at 14:06