Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как нарисовать точку на канве в FireMonkey?


rareMax

Вопрос

Добрый вечер. Помогите  с таким вопросом. Пытаюсь сделать эффект "Падающих звезд" для Android. Но не получается даже нарисовать точку на канве. Взял ваш пример с форума:

procedure TForm9.Panel1Click(Sender: TObject);
var
  M: TBitmapData;
  i, j: integer;
begin
  if Panel1.Canvas.Bitmap.Map(TMapAccess.maWrite, M) then
    try
      for i := 0 to Panel1.Canvas.Bitmap.Width - 1 do
        for j := 0 to Panel1.Canvas.Bitmap.Height - 1 do
          M.SetPixel(i, j, TAlphaColorRec.Red);
    finally
      Panel1.Canvas.Bitmap.Unmap(M);
    end;
  // Stars1.Stars := not Stars1.Stars;
end;

Но даже при его запуске получаю ошибку: 

 

First chance exception at $005537A3. Exception class $C0000005 with message 'access violation at 0x005537a3: read of address 0x00000040'. Process Project10.exe (3228)

Если нажать на Break то кидает на функцию 

function TBitmap.GetCanvasClass: TCanvasClass;
begin
  if not Assigned(FCanvasClass) then
    FCanvasClass := TCanvasManager.GetDefaultCanvas;
  Result := FCanvasClass;
end;

Собственно вопрос: Как нарисовать точку на канве в FMX?

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
  • Администраторы

Добрый вечер

 

В моей статье, я описывал способ работы с TBitmap. В вашем же случае, вы работаете с канвой. У канвы формы нету Bitmap. Поэтому ваш код падает при попытке вызывать Map у не существующего объекта.

 

Для решения вашей задачи, нужно:

  1. Помнить о самое главной вещи при работе с канвой в FMX. Это то, что выполнять отрисовку можно только в определенный моменты времени (в отличии от VCL). Непосредственно, когда получен системный запрос на отрисовку сцены (формы), а именно в событиях OnPaint, OnPainting (в вашем случае у панели). 
  2. Знать, что канва существует в единственном экземпляре в рамках одной формы (опять же в отличии от VCL, где свою канву имеет каждый оконный контрол).

Резюмирую, все выше сказанное.

procedure TForm4.Panel1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
  X, Y: Integer;
  PixelRegion: TRectF;
begin
  Canvas.Stroke.Color := TAlphaColorRec.Red;
  for X := 0 to Floor(Panel1.Width) - 1 do
    for Y := 0 to Floor(Panel1.Height) - 1 do
    begin
      PixelRegion := TRectF.Create(TPointF.Create(X, Y), 1, 1);
      Canvas.DrawRect(PixelRegion, 0, 0, AllCorners, 1);
    end;
end;

Задаем обработчик на событие TPanel.OnPaint. Используя канву переданную через параметры, задаем цвет кисти и отрисовываем логические пиксели. Для закраски пикселей, я воспользовался обычной отрисовкой квадрата с шириной в 1 логический пиксель.

 

Если речь идет об андроиде, то из-за возможного наличия экрана с повышенной плотностью пикселей (Screen Scale) это код для экранов со Scale отличных от 1 и не кратных 2, будет рисовать сдвоенные/размазанные линии. Чтобы этого избежать, нужно перед отрисовкой выполнить округление региона до физических пикселей при помощи метода TCanvas.AlignToPixel.

procedure TForm4.Panel1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
  X, Y: Integer;
  PixelRegion: TRectF;
  PixelPos: TPointF;
begin
  Canvas.Stroke.Color := TAlphaColorRec.Red;
  for X := 0 to Floor(Panel1.Width) - 1 do
    for Y := 0 to Floor(Panel1.Height) - 1 do
    begin
      PixelPos := Canvas.AlignToPixel(TPointF.Create(X, Y));
      PixelRegion := TRectF.Create(PixelPos, 1, 1);
      Canvas.DrawRect(PixelRegion, 0, 0, AllCorners, 1);
    end;
end;
Ссылка на комментарий
  • 0
  • Администраторы

 

А почему когда пишу так:

Image14.Canvas.Stroke.Color := TAlphaColorRec.Red;
PixelRegion := TRectF.Create(TPointF.Create(100,100),20,20);
Image14.Canvas.DrawEllipse(PixelRegion,1);
То в Win всё видно, а на девайсе не видно?

 

 

У меня просьба. На форуме пока негласное правило. Одна тема - один вопрос. В этой теме ответ уже был дан. Если вас интересует ответ на вашу ситуацию, оформите это отдельным вопросом. Так же нужно подробно описать вашу ситуацию. Чем подробнее и полнее будет описание вопроса, тем вероятнее на него и точнее будет ответ. Например в вашей ситуации нужно обязательно указать место, где вы пытаетесь выполнить отрисовку. А так же приложить скриншоты, подтверждающие, что на Windows и устройстве результат отрисовки разный.

 

Спасибо за понимание.

Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...