I'm trying to draw text on image using the below code :
procedure TfMain.TextToImage(const AText: string; const AImage: TImage);
begin
if NOT Assigned(AImage) then Exit;
AImage.Canvas.BeginScene;
AImage.Canvas.Font.Size := 18;
AImage.Canvas.Font.Family := 'Arial';
AImage.Canvas.Fill.Color := TAlphaColorRec.Dodgerblue;
AImage.Canvas.Font.Style := [TFontStyle.fsbold];
AImage.Canvas.FillText( AImage.AbsoluteRect,
AText,
False,
1,
[TFillTextFlag.RightToLeft],
TTextAlign.taCenter,
TTextAlign.taCenter);
AImage.Canvas.EndScene;
end;
Q: Why the above procedure works on Windows but not in android ?
Try to draw directly on the TBitmap
of the timage instead of the Canvas of the TImage.
You need also to create a bitmap of your image before you try to access it:
AImage.Bitmap := TBitmap.Create(Round(AImage.Width), Round(AImage.Height));
So the correct code will be something like this:
procedure TfMain.TextToImage(const AText: string; const AImage: TImage);
begin
if NOT Assigned(AImage) then Exit;
AImage.Bitmap := TBitmap.Create(Round(AImage.Width), Round(AImage.Height));
AImage.Bitmap.Canvas.BeginScene;
try
//....
// Use AImage.Bitmap.Canvas as needed
AImage.Bitmap.Canvas.FillText( AImage.AbsoluteRect,
AText,
False,
1,
[],
TTextAlign.Center,
TTextAlign.Center);
finally
AImage.Bitmap.Canvas.EndScene;
end;
end;
From the TImage.Paint
event code you will see:
procedure TImage.Paint;
var
R: TRectF;
begin
if (csDesigning in ComponentState) and not Locked and not FInPaintTo then
begin
R := LocalRect;
InflateRect(R, -0.5, -0.5);
Canvas.DrawDashRect(R, 0, 0, AllCorners, AbsoluteOpacity, $A0909090);
end;
UpdateCurrentBitmap;
if FCurrentBitmap <> nil then
DrawBitmap(Canvas, LocalRect, FCurrentBitmap, AbsoluteOpacity);
end;
So no matter what you will paint on the canvas, on the next repaint it will draw again the full bitmap erasing what you already done.
If you don't want to touch the bitmap than you need to override the OnPaint
event of theTImage
and call function TextToImage(const AText: string; const AImage: TImage);