Изображение на холсте вместо этого попадает в форму

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

  • Кто-нибудь знает, почему Image.Canvas.DrawArc (etc) рисует относительно родительской формы, а не относительно изображения?
  • Если я столкнусь с проблемой .LocalToAbsolute ... почему дуга выглядит так иначе?

Проект прост: форма Firemonkey HD с TPanel посередине и TImage внутри TPanel (согласованная с клиентом). Кнопка просто выполняет код.

Вот код:

    unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  FMX.Objects;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}


procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Canvas.BeginScene;

  {Trying to draw arc and line on Image's canvas - Doesn't work; it draws to Form's canvas instead}
  Image1.Canvas.DrawArc(PointF(0,0), PointF(10, 10), 0.0, 45.0, 1.0);
  Image1.Canvas.DrawLine(PointF(0.0, 0.0), PointF(100, 100), 1.0);

  {Trying to draw arc and line on Image's canvas - This works; by why should such steps be necessary and why is the arc so different?}
  Image1.Canvas.DrawArc(Image1.LocalToAbsolute(PointF(0,0)), Image1.LocalToAbsolute(PointF(10, 10)), 0.0, 45.0, 1.0);
  Image1.Canvas.DrawLine(Image1.LocalToAbsolute(PointF(0.0, 0.0)), Image1.LocalToAbsolute(PointF(100, 100)), 1.0);

  Image1.Canvas.EndScene;
end;

end.

person Jeffam70    schedule 15.07.2014    source источник
comment
Включите общий тег delphi в свои вопросы, связанные с delphi   -  person Sir Rufo    schedule 16.07.2014
comment
Нет XE6, но в XE5 вы должны рисовать на холсте растрового изображения, то есть Image1.Bitmap.Canvas.DrawArc (PointF (0,0), PointF (10, 10), 0.0, 145.0, 1.0);   -  person LHristov    schedule 16.07.2014
comment
@SirRufo Спасибо за советы! Я сделаю это в следующий раз.   -  person Jeffam70    schedule 17.07.2014
comment
@LHristov Спасибо. Я пробовал это только сейчас, но это не решило проблему. Я изменил код (между BeginScene и EndScene) на Image1.Bitmap.Canvas.DrawArc(PointF(0,0), PointF(10, 10), 0.0, 145.0, 1.0); Image1.Bitmap.Canvas.DrawLine(PointF(0.0, 0.0), PointF(100, 100), 1.0); Первый, похоже, вообще ничего не делает, а второй вызывает исключение с попыткой доступа к адресу 0x00000000.   -  person Jeffam70    schedule 17.07.2014
comment
Я добавлю ответ с измененным кодом   -  person LHristov    schedule 17.07.2014


Ответы (2)


Как я уже упоминал, это для XE5. Вот ваш код:

procedure TForm3.Button1Click(Sender: TObject);
begin
  Image1.Bitmap.Canvas.BeginScene;

  {Trying to draw arc and line on Image's canvas - Doesn't work; it draws to Form's canvas instead}
  Image1.Bitmap.Canvas.DrawArc(PointF(0,0), PointF(10, 10), 0.0, 145.0, 1.0);
  Image1.Bitmap.Canvas.DrawLine(PointF(0.0, 0.0), PointF(200, 200), 1.0);

  {Trying to draw arc and line on Image's canvas - This works; by why should such steps be necessary and why is the arc so different?}
  Image1.Bitmap.Canvas.DrawArc(Image1.LocalToAbsolute(PointF(0,0)), Image1.LocalToAbsolute(PointF(10, 10)), 0.0, 45.0, 1.0);
  Image1.Bitmap.Canvas.DrawLine(Image1.LocalToAbsolute(PointF(0.0, 0.0)), Image1.LocalToAbsolute(PointF(100, 100)), 1.0);

  Image1.Bitmap.Canvas.EndScene;

end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  Image1.Bitmap:=TBitmap.Create(trunc(image1.Width),trunc(image1.Height));
end;

Вы не вставили процедуру создания растрового изображения.

person LHristov    schedule 17.07.2014
comment
Установка Image1.Bitmap внутренне вызывает Bitmap.Assign. Следовательно, вы просочите TBitmap. - person Sebastian Z; 18.07.2014
comment
Что ж, я чувствую себя глупо из-за того, что не создал растровое изображение. Ой! Но либо они что-то изменили в XE6, либо я все еще делаю что-то не так, потому что мой код с внесенными вами изменениями не отображается. Попробую сделать резервную копию и запустить в XE5 для подтверждения. - person Jeffam70; 19.07.2014
comment
@Sebastian Z: Да, но тогда требуется Image1.Bitmap.SetSize, поскольку рисование на растровом изображении 0x0 вызывает исключение - person LHristov; 20.07.2014

Ну, у меня тоже были проблемы с этим, и вы должны использовать Bitmap, как сказал @LHristov. Единственное, что есть ошибка, которая не устанавливает размер растрового изображения правильно, и исправление для этого выглядит следующим образом:

procedure TForm3.FormCreate(Sender: TObject);
begin
  bitmap := TBitmap.Create;
  bitmap.SetSize(round(Image1.Width), round(Image1.Height));
  Image1.MultiResBitmap.Bitmaps[1].Assign(bit);
  Image1.Bitmap := Image1.MultiResBitmap.Bitmaps[1];
  Image1.Bitmap.Clear(TAlphaColorRec.White);
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  Image1.Bitmap.Canvas.BeginScene;

  Image1.Bitmap.Canvas.DrawArc(PointF(0,0), PointF(10, 10), 0.0, 145.0, 1.0);
  Image1.Bitmap.Canvas.DrawLine(PointF(0.0, 0.0), PointF(200, 200), 1.0);

  Image1.Bitmap.Canvas.DrawArc(Image1.LocalToAbsolute(PointF(0,0)), Image1.LocalToAbsolute(PointF(10, 10)), 0.0, 45.0, 1.0);
  Image1.Bitmap.Canvas.DrawLine(Image1.LocalToAbsolute(PointF(0.0, 0.0)), Image1.LocalToAbsolute(PointF(100, 100)), 1.0);

  Image1.Bitmap.Canvas.EndScene;

end;

Надеюсь, это решит эту проблему за вас!

person Remi    schedule 08.08.2014