Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: I'm trying to copy/move a control by copying its Canvas.Bitmap elsewhere...


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Sep 21, 2017 11:59 AM Last Post By: Free Dorfman
Free Dorfman

Posts: 139
Registered: 2/4/12
I'm trying to copy/move a control by copying its Canvas.Bitmap elsewhere...  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 19, 2017 8:43 PM
I think the following should be enough information. [Seattle * Delphi * FMX * Windows 10 * 32-bit]
TmdTileBtn = class(TRectangle)
  :
 
procedure TdfMainForm.zzzTempBtnClick(Sender: TObject);
var
  Btn: TmdTileBtn;
  LAY: TLayout;
begin
//I am not invoking this method until these buttons are
//fully drawn, and visible onscreen
 
Assert(Assigned(mdArena.TileBtns[0]));
Btn := mdArena.TileBtns[0];
 
Assert(Assigned(Btn)); //ok
Assert(Assigned(Btn.Canvas)); //ok
Assert(Assigned(Btn.Canvas.Bitmap)); //FAIL! <<------
 
LAY := TLayout.Create(Self);
LAY.Parent := Self;
LAY.Position.X := 50;
LAY.Position.Y := 500;
LAY.Width := Btn.Canvas.Width;
LAY.Height := Btn.Canvas.Height;
LAY.Canvas.CopyBitmap(Btn.Canvas.Bitmap,LAY.Canvas.Bitmap); //<--SPLAT w/o the above Assertions
//here I'd like to have LAY available (a "copy" of 
//the Btn) to "move and animate" it 
 :
 :
end;


My questions are:
(1) How can the Canvas.Bitmap be nil there? If it's nil there, can I assume it's NEVER used?
(2) In general, is this a good approach for "leaving the button onscreen" while also "copying/moving it" to
a new location?

UPDATE


on further testing, i.e. making the following changes to the above code:
Btn := mdArena.TileBtns[0];
BMP := Btn.MakeScreenshot;
 :
 :
LAY.Canvas.CopyBitmap(BMP,LAY.Canvas.Bitmap); //<-- SPLAT!


I get an AV attempting to call CopyBitmap

So:


I tried the following:
procedure TdfMainForm.zzzTempBtnClick(Sender: TObject);
var
  control: TRectangle;
begin
control := TRectangle.Create(Self);
control.Parent := Self;
control.SetBounds(10,10,100,40);
Assert(Assigned(control.Canvas));
Assert(Assigned(control.Canvas.Bitmap)); //FAIL <---

So.. it seems as if no TCanvas ever has a Bitmap property which is instantiated.
Note that in the previous snippet, I do get a TRectangle on the screen. Then the
assertion fails.

How does one copy a Bitmap to a Canvas?


As always, your input is greatly appreciated.
loki loki

Posts: 787
Registered: 7/1/02
Re: I'm trying to copy/move a control by copying its Canvas.Bitmap elsewhere... [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 19, 2017 11:58 PM   in response to: Free Dorfman in response to: Free Dorfman
on android/ios you are working with opengl, and with opengl everything
is draw on an internal surface. then their is no individual "bitmap" for
each control

if you want each control to have their individual bitmap (i prefere to
say their own internal texture), you can use double buffered alcinoe
control suite. however what you are trying to do is not the good way to
move and animate a btn, you must instead simply update his position

On 9/20/2017 8:14 AM, Free Dorfman wrote:

I think the following should be enough information. [Seattle * Delphi * FMX * Windows 10 * 32-bit]
TmdTileBtn = class(TRectangle)
   :
 
procedure TdfMainForm.zzzTempBtnClick(Sender: TObject);
var
   Btn: TmdTileBtn;
   LAY: TLayout;
begin
//I am not invoking this method until these buttons are
//fully drawn, and visible onscreen
 
Assert(Assigned(mdArena.TileBtns[0]));
Btn := mdArena.TileBtns[0];
 
Assert(Assigned(Btn)); //ok
Assert(Assigned(Btn.Canvas)); //ok
Assert(Assigned(Btn.Canvas.Bitmap)); //FAIL! <<------
 
LAY := TLayout.Create(Self);
LAY.Parent := Self;
LAY.Position.X := 50;
LAY.Position.Y := 500;
LAY.Width := Btn.Canvas.Width;
LAY.Height := Btn.Canvas.Height;
LAY.Canvas.CopyBitmap(Btn.Canvas.Bitmap,LAY.Canvas.Bitmap); //<--SPLAT w/o the above Assertions
//here I'd like to have LAY available (a "copy" of
//the Btn) to "move and animate" it
  :
  :
end;


My questions are:
(1) How can the Canvas.Bitmap be nil there? If it's nil there, can I assume it's NEVER used?
(2) In general, is this a good approach for "leaving the button onscreen" while also "copying/moving it" to
a new location?

UPDATE


on further testing, i.e. making the following changes to the above code:
Btn := mdArena.TileBtns[0];
BMP := Btn.MakeScreenshot;
  :
  :
LAY.Canvas.CopyBitmap(BMP,LAY.Canvas.Bitmap); //<-- SPLAT!


I get an AV attempting to call CopyBitmap

So:


I tried the following:
procedure TdfMainForm.zzzTempBtnClick(Sender: TObject);
var
   control: TRectangle;
begin
control := TRectangle.Create(Self);
control.Parent := Self;
control.SetBounds(10,10,100,40);
Assert(Assigned(control.Canvas));
Assert(Assigned(control.Canvas.Bitmap)); //FAIL <---

So.. it seems as if no TCanvas ever has a Bitmap property which is instantiated.
Note that in the previous snippet, I do get a TRectangle on the screen. Then the
assertion fails.

How does one copy a Bitmap to a Canvas?


As always, your input is greatly appreciated.
Free Dorfman

Posts: 139
Registered: 2/4/12
Re: I'm trying to copy/move a control by copying its Canvas.Bitmap elsewhere... [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 21, 2017 11:59 AM   in response to: loki loki in response to: loki loki
loki,

I appreciate this feedback. I did a bunch of research before posting and came across your name and this info already.

Without getting into everything specific to my needs, and (being totally honest - if it's not painfully obvious :`) I am still learning a lot here. Still, my understanding is that the entire form is always updated. So, I don't understand why this is "wrong". And, I am over-simpifying when I say "copy and move". I have specific needs to grab part of the "screen" and (without touching the image - or control - that's already there) to now move and further animate the image.

Right now I have (almost working - except that the copied image is too big on Android):

type
  TXRectangle = class(TRectangle)
  protected
    procedure Paint; override;
  public
    BMP: TBitmap;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;
//=====
constructor TXRectangle.Create;
begin
inherited;
BMP := TBitmap.Create;
end;
 
destructor TXRectangle.Destroy;
begin
BMP.Free;
inherited;
end;
 
procedure TXRectangle.Paint;
var
  R: TRectF;
begin
inherited;
R := RectF(0,0,Width,Height);
Canvas.DrawBitmap(BMP,R,R,AbsoluteOpacity);
end;
//===
function jCreateGrabbedRect(C: TControl; AParent: TFmxObject = nil): TXRectangle;
var
  BMP: TBitmap;
  R: TXRectangle;
begin
BMP := C.MakeScreenshot;
 
if AParent = nil then
  AParent := C.Parent;
 
R := TXRectangle.Create(AParent);
R.BMP.Assign(BMP);
R.Parent := AParent;
R.Width := BMP.Width;
R.Height := BMP.Height;
R.Fill.Color := TAlphaColorRec.Null;
R.Stroke.Color := TAlphaColorRec.Null;
 
BMP.Free;
 
result := R;
end;
//===
procedure TmdArena.Test;
label
  DONE;
const
  isOn: boolean = false;
  RX: TXRectangle = nil;
var
  Anim: TFloatAnimation;
begin
isOn := not isOn;
if not isOn then
  begin
  jDropControl(RX);
  exit;
  end;
 
RX := jCreateGrabbedRect(TileBtns[0]);
RX.Position := TileBtns[0].Position;
 
Anim := TFloatAnimation.Create(RX);
Anim.Parent := RX;
Anim.PropertyName := 'Position.Y';
Anim.StartValue := 500;
Anim.StopValue := RX.Position.Y;
Anim.Interpolation := TInterpolationType.Quadratic;
Anim.Duration := 1.11;
Anim.Enabled := true;
end;


I did start down the road of creating another control and Assign-ing it. Except I have a number of TText objects that can't be assigned. So - either way - wrong size in Android, or redoing the TText controls -- I have some work to do here.

Before I go down one road or the other, I would really appreciate understanding why the "grab & copy" approach is wrong.

Is it inefficiency? Is it not truly cross-platform? Is it just standard practice?

Thanks Again !
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02