Сохранение содержимого TPaintBox Canvas в растровое изображение (и / или файл) в Delphi 10.3 Firemonkey - PullRequest
0 голосов
/ 28 февраля 2020

Delphi 10.3.3 Приложение Firemonkey для Android. Я рисую множество объектов в TPaintBox Canvas в событии OnPaint. Теперь мне нужно сохранить все содержимое PaintBox.Canvas в растровое изображение и, наконец, в файл . Как это можно сделать? Читайте RAD документы, гуглите inte rnet - не можете найти решение.

UPDATE1:

Следуя комментариям @MBo, @ Remy-Lebeau, @ Adam-Henderson Я пытался, но это только 50% успеха ...

Я создал

procedure GameCanvasPaint(Canvas: TCanvas);

В событии PaintBox OnPaint, которое я вызываю, drawint успешно:

procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
  GameCanvasPaint( Canvas );
end;

и теперь я хочу создать растровое изображение и поделиться им, также вызывая ту же самую болевую функцию:

procedure TForm1.ShowShareSheetAction1BeforeExecute(Sender: TObject);
begin
// g_bmp_share is TBitmap already created earlier
  g_bmp_share.SetSize( Paintbox1.Canvas.Width, Paintbox1.Canvas.Height );
  g_bmp_share.Canvas.Clear($FFFFFF);
  GameCanvasPaint( g_bmp_share.Canvas );
  ShowShareSheetAction1.Bitmap.Assign( g_bmp_share );
end;

РЕЗУЛЬТАТ: Общая фотография с черным цветом ... Ничего на нем нет , только черный . Кто может посоветовать почему?

1 Ответ

2 голосов
/ 29 февраля 2020

Переместите ваш код рисования в функцию многократного использования, которая принимает TCanvas в качестве ввода, тогда ваш обработчик OnPaint может вызывать функцию с помощью холста TPaintBox, а код сохранения - функцию с * 1004. * canvas.

Обратите внимание, что при рисовании на холсте FMX TBitmap необходимо сначала вызвать Canvas.BeginScene():

Уведомляет объект TCanvas что рисование может начаться.

Вызовите BeginScene перед рисованием на TCanvas.

Чтобы завершить сеанс рисования, вызовите EndScene.

procedure TForm1.GameCanvasPaint(Canvas: TCanvas);
begin
  //...
end;

procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
  GameCanvasPaint( Canvas );
end;

procedure TForm1.ShowShareSheetAction1BeforeExecute(Sender: TObject);
begin
  // g_bmp_share is TBitmap already created earlier
  g_bmp_share.SetSize( Paintbox1.Width, Paintbox1.Height );
  if g_bmp_share.Canvas.BeginScene then
  try
    g_bmp_share.Canvas.Clear($FFFFFF);
    GameCanvasPaint( g_bmp_share.Canvas );
  finally
    g_bmp_share.Canvas.EndScene;
  end;
  ShowShareSheetAction1.Bitmap.Assign( g_bmp_share );
end;

Вам не нужно делать это в событии OnPaint, поскольку FMX вызывает для вас BeginScene() перед запуском события:

Совет: обратите внимание, что вызов BeginScene в обработчиках событий OnPaint не имеет никакого эффекта, потому что BeginScene вызывается до того, как обработчик события OnPaint запустит . Это гарантирует, что рисование всегда происходит в OnPaint, не требуя дополнительного и, возможно, неожиданного кода, позволяющего рисованию иметь эффект.

...