Перейти к содержанию

Вопросы

Исходно пытался нарисовать битмап на канве формы. Затем пытался нарисовать хоть что-нибудь. Все время получаю пустой экран. При этом аналогично ничего не получается и с TImage и с PaintBox. Проект на С++, Embarcadero XE7. Что я делаю не так?

SolverMXE7.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

  • 0

В FireMonkey в отличии от VCL нельзя рисовать на канве формы в произвольном месте. Рисование должно выполняться в отведенных местах: OnPaint, Paint, Painting

Всю отрисовку на канве формы нужно выполнять в событии OnPaint.

 

В вашем случае, вам нужно рисовать в TForm.OnPaint. А в событии таймера выполнять вызов Repaint.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спсибо за ответ. Через OnPaint действительно работает. Однако у меня пиявилось еще несколько вопросов:

 

  1. В интернете много примеров, когда рисование все же идет по нажатию кнопки. Вот например: http://docwiki.embarcadero.com/CodeExamples/XE6/en/FMXTCanvasDrawFunctions_(Delphi) (этот примечателен еще и тем, что он от самой Embarcadero) Я вижу что он для XE6, в XE7 что-то изменилось (я уже заметил, что BitmapChanged стал приватным) ? Возможно ли как-то обойти ограничение на рисование только в OnPaint?
  2. У TImage и PaintBox действительно есть метод Repaint, а вот у  формы такого метода нет. Что лучше использовать если я таки хочу рисовать на форме?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

На счет примера на DocWiki. Обратите внимание, что там идет отрисовка на канве TBitmap, а не на канве формы. На канве TBItmap можно рисовать из любого места. Главное помнить, что процесс рисования на канве в FireMonkey имеет три фазы:

  1. BeginScene - начало отрисовки
  2. Любая отрисовка на TCanvas
  3. EndScene - окончание рисования.

На счет формы, вместо Repaint у формы есть метод Invalidate.

Чтобы выполнить отрисовку в любом другом месте, можно сделать дополнительный буфер в виде TBitmap. И выполнять в любом месте отрисовку там. А в OnPaint у формы просто выводить сформированное изображение из TBitmap.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо. Ну и последний вопрос. А можно как-то отключить очистку канвы? Т.е. чтобы OnPaint рисовал новую картинку поверх старой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Отключить нет. Форма сама определяет при помощи контролов, какие области формы нужно перерисовать. Поэтому, если нужно добиться такого эффекта, то лучше использовать опять же временный буфер. И в нем делать наложение своей картинки на старую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

пытаюсь в приложении для Android просто вывести хоть какое-то изображение, но ничего не выходит. Делаю так в событии формы OnPaint:

 

      if Canvas.BeginScene then
      try
      Canvas.DrawLine(form1.ClientRect.TopLeft,form1.ClientRect.BottomRight,1);
      Canvas.DrawEllipse(Rectf(0,0,50,50),1);
      finally
      Canvas.EndScene;
      end;

 

Но выходит просто черный экран и все. Если убрать прорисовку эллипса, то риуется просто белый екран. Вообще для игры нужно вывести битмап на форму, но даже такие примитивы не выходит вывести. не могу понять почему? Больше никакого кода в проекте нет.

 

Если без этого кода просто на форму накидать компонентов imagecontrol и загрузить вних изображения, то их видно в приложении.

 

И еще вопрос. Вы ранее написали, что

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

И еще вопрос. Вы ранее написали, что можно в таймере вызывать Repaint; Но такого свойства в форме нет и в ее канве, по крайней мере RadStudio XE6 не предлагает такого варианта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Добрый вечер,

  1. В обработчике события OnPaint не нужно вызывать BeginUpdate/EndUpdate.
  2. Вместо Repaint у формы есть Invalidate.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Добрый день!

Есть такая ситуация, если рисовать часто в цикле и большое изображение например на Timage, например так

 

ImageDraw.Bitmap.Canvas.BeginScene();
ImageDraw.Bitmap.Canvas.DrawBitmap(ASourceBmp,
rctCurSource,rctDest, 1);
ImageDraw.Bitmap.Canvas.EndScene();

 

То появляется эффект задержки, т.е цикл идет дальше а изображение меняется с задержкой, если цикл остановить то картинка продолжает менятся еще раз 10... Пробовал убрать прорисовку в OnPaint и вызывать событие по таймеру, но кажется эффект тотже. Пробовал рисовать на PaintBox но кажется тоже самое...

 

Сталкивался ли кто с таким? с чем это связано? Как можно рисовать напрямую, т.е рисуешь и событие отображается на экране в этот же момент...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

все верно

закончится цикл, программа исполнит рисование. 

пока программа исполняет цикл, кто будет перерисовывать экран ??

В VCL можно было вызывать в цикле Repaint для этого, тут вроде UpdateRect есть.

тут нужно в отдельном потоке готовить картинки для рисования и говорить форме Invalidate, а в OnPaint очевидно эти картинки выводить на форму

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

тут нужно в отдельном потоке готовить картинки для рисования и говорить форме Invalidate, а в OnPaint очевидно эти картинки выводить на форму

В общем я это понимаю, но когда работа ведется в отдельном потоке что бы что то подготовить на bmp приходится вызывать метод Synchronize, т.е он выполняется в главном потоке как я понимаю, т.е в этом же потоке в методе Synchronize я и пытаюсь рисовать на TImage.Bitmap , что достаточно удобно. Но есть проблемы первое это при активном рисование , проще говоря в цикле, похоже как возникает запаздывание прорисовки, хотя может это моя ошибка в коде...(так как там идет передача данных по сети) и вторая проблема это иногда приложение вылетает, просто без ошибки без ничего процесс в Андроиде завершается. Вот и хотел спросить у более опытных что делать.  Хотел рисовать в OnPaint но появляется какое то мерцание , поэтому рисование на битмап гораздо лучше на вид...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

В общем немного разолбрался дело не в прорисовке а в сети, тут в FMX есть какой то буфер, т.е если не вызывать метод ReadStraem какое то время, то в системе все данные накапливаются в какойто буфер, потом чтение идет из него... причем явно есть какое то граничение на размер этих данных после чего из сети данные перестают читаться и все работает как в Винде. Флаг UseNagle я отключил сразу.

Может кто с таким сталкивался? как его отключить или уменьшить

 

2 да и вторая проблема осталась, программа почему то иногда при просировке зависает или вообще вылетает непонятно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Помогите разобраться. сделал как вы советовали, разместил отрисовку на Canvas в событии OnPaint главной формы. Для Винды все рисует нормально, а вот для Андроида пустой экран

Код

procedure TForm6.FormPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
  var
  R: TRectF;
begin
 r:= TRectF.Create(20,20,200,200);
 Canvas.BeginScene;
 Canvas.Stroke.Color:= TAlphaColorRec.Black;
 Canvas.DrawEllipse(R,1);
 Canvas.EndScene;
end;
 
Что я сделал не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

на сколько помню нужно плясать от координат ARect

Попробовал вместо R подставить  ARect. Результат тот же: в Винде элипс на весь экран, а на телефоне - пусто

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Почему на мобильных платформах у меня не рисуется окружность?

Отредактировал Andrey Efimov
Исправил ссылку

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо большое, вроде нарисовалось.

Судя по вашим ответам, вы большой спец в этой области. не могли бы посоветовать хорошую книгу или другие источники по программированию для андроид на последних Делфи. А то приходится тыкаться как слепой котенок (Делфи 7, на котором раньше программировал, сильно отличается от ХЕ8)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

Спасибо большое, вроде нарисовалось.

Судя по вашим ответам, вы большой спец в этой области. не могли бы посоветовать хорошую книгу или другие источники по программированию для андроид на последних Делфи. А то приходится тыкаться как слепой котенок (Делфи 7, на котором раньше программировал, сильно отличается от ХЕ8)

 

спец) он один из разработчиков Firemonkey

Отредактировал ZuBy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

 

Спасибо большое, вроде нарисовалось.

Судя по вашим ответам, вы большой спец в этой области. не могли бы посоветовать хорошую книгу или другие источники по программированию для андроид на последних Делфи. А то приходится тыкаться как слепой котенок (Делфи 7, на котором раньше программировал, сильно отличается от ХЕ8)

 

спец) он один из разработчиков Firemonkey

 

ну тогда особое уважение: работать и находить время на общение со слепыми котятами типа меня - это ж какая сила воли нужна

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От Botov Nikita
      Добрый день Уважаемые!
      Подскажите каким образом можно реализовать функцию ластика в XE 10.3?
      Например на форме лежит 2 TImage один над другим, и когда мышкой проводим по верхней картинке, остается "след" и видно нижнюю картинку?
      С Уважением!
    • От Павел Блажеев
      Добрый день. Очень нужна Ваша помощь. 
      Мне необходимо сделать координатную сетку в виде точек. При масштабировании панели количество точек должно изменяться . 
      Хочу все это сделать на канве панели. Унаследовал класс и переопределил procedure   Paint; override;
        Tfield = class(TPanel)
            Constructor Create( parent: TFmxObject);
              procedure   Paint; override;
              Procedure   OnMyClick (Sender: TObject);
          end;

      В теле метода я пробовал рисовать. Экспериментировал и столкнулся с такой проблемой. Ничего не отображается. Нет никаких изменений.
      Если я наследую не от Tpanel а от Timage то часть кода работает а часть работает очень криво. Очень хочу разобраться почему .
      {Отображается сразу}
      for a:=1 to 1000 do
            begin
              self.Canvas.Fill.Color:=  TAlphaColors.Crimson;
               self.Canvas.FillEllipse(rect(1,1,10,10),self.AbsoluteOpacity);
               self.Canvas.FillEllipse(rect(round(self.Width-9),round(self.Height-9),round(self.Width), round(self.Height)),self.AbsoluteOpacity);
               self.Canvas.FillEllipse(rect(round(self.Width-9),1,round(self.Width), 9),self.AbsoluteOpacity);
               self.Canvas.FillEllipse(rect(1,round(self.Height-9),10, round(self.Height)),self.AbsoluteOpacity);
            end;
       
      {Отображается только после того как я проскролю Scrollbox на котором лежит панель в крайнее нижнее правое положение}
            self.Canvas.Stroke.Color:=  TAlphaColors.Crimson;
            self.Canvas.Stroke.Thickness:=7;
             Canvas.BeginScene;
            self.Canvas.DrawLine(PointF(20, 20), PointF(100, 50), self.AbsoluteOpacity);
             Canvas.EndScene;
      Подскажите пожалуйста, почему не работает такое с панелью?  Как правильно рисовать на панели? 
      Почему в случае с имейджем все работает так некорректно?  Почему работает только после скрола? 
      Каким способом мне лучше сделать координатную сетку? состоящую из точек как в режиме Design?

       


    • От Serg Sib
      RAD 10.2.3 Delphi , Win 10x64 Pro 1803
      Подскажите, с помощью чего можно осуществить трансформацию изображения по опорным точкам (по углам)?
      Возможно, что не напрямую сам TImage, а при помощи работы с Canvas на его Bitmap.
      Пока удалось добиться подобной трансформации, заполнив нужным изображением полигон и, меняя координаты его вершин, делать нужные корректировки.
      var MyBrushBitmap: TBrushBitmap; Image1.Bitmap.Canvas.Fill.Kind := TBrushKind.Bitmap; Image1.Bitmap.Canvas.Fill.Bitmap := MyBrushBitmap; Image1.Bitmap.Canvas.Fill.Bitmap.WrapMode := TWrapMode.TileStretch; Image1.Bitmap.Canvas.FillPolygon(MyPolygon, 50); Однако, изображение частично обрезается при этом.
      В интернете поиском находил пример подобной трансформации на VCL, (перетаскиванием вершин мышью), но не смог приспособить этот пример для платформы FireMonkey.
    • От Tot999
      Добрый день! 
      Решил покопаться в своей старой спрайтовой игрушке, чтобы освежить в памяти знания и состряпать что-нибудь новое. Возникли сомнения, нормально ли сделано графическое отображение, можно ли доработать.
      Все спрайты в дизайнтайме распиханы по Timagelist-ам.  На старте приложения я загружаю битмапы из имэджлистов в свои обджектлисты, подгоняя под нужный размер. 
      MeduzasBitmpAr : array [1..numofMeduzas] of TObjectList<Tbitmap>;  
      Дальше рисую по таймеру в основном окне игры Tpaintbox.OnPaint:
               
      В принципе, даже на слабеньких телефончиках, всё вроде бодро. Но может, опытные товарищи чего подскажут, а то я 3ий день в собственном соку варюсь, ничего толкового.
    • От Tumaso
      Столкнулся со следующей проблемой - TImage игнорирует установленные значения XRadius и YRadius у TRectangle (10.1 Berlin with update 2)
       
      Суть - мне необходимо, чтобы у TRectangle углы были немного скругленные, для этого я устанавливаю XRadius и YRadius. Внутри TRectangle расположен TImage (левый верхний угол 0,0, ширина и высота совпадают с размерами TRectangle). Когда я загружаю картинку в TImage (что в дизайнере, что программно), получается что TImage отображается с прямыми углами, игнорируя XRadius и YRadius своего родителя. Свойство ClipChildren у TRectangle установлен.
      Как сделать так, чтобы TImage скруглялся по углам? Что интересно, TCircle в этом плане работает, обрезая TImage.
    • От yooSee
      Привет ребят, созрел такой вопрос который меня мучает ! Вобщем пытаюсь загрузить картинку по прямой слыке с сервера. Картинка не грузится, не сохраняется не отображается. 
      Конечная платформа - Андроид. Пишу на Delphi xe 10 seatle.
      Что я делаю? при нажатии на сам компонент TImage (созданный динамически), должна грузится картинка по адресу преждевременно записанное в hint (TImage) при создании вида (http://блаблабла.jpg)
      Раньше код ниже работал сейчас нет не пойму что не так. Почему стал ковырять? потому что форма встает колом при загрузке изображений.
       
      var s: string; fs: TFileStream; begin fs := TFileStream.Create(tpath.Combine(tpath.GetDownloadsPath, 'load.jpg'), fmCreate); NetHTTPClient1.Get((Sender as TImage).Hint, fs); fs.Free; (Sender as TImage).MultiResBitmap.Bitmaps[1].LoadFromFile (tpath.Combine(tpath.GetDownloadsPath, 'load.jpg')); подключал еще pas нашел на этом форуме FMX.Features.Bitmap.Helpers.pas
      (Sender as TImage).MultiResBitmap.Bitmaps[1].LoadFromUrl ((Sender as TImage).Hint); как проще сделать посоветуете чтоб и грузилось и форма не висла?
    • От Anasazi
      Всем доброго времени суток. Возникла необходимость решить такую задачу: в таблице базы MySQL хранится список изображений и их URL. Необходимо получить этот список массивом. Затем загрузить изображения и поочередно с интервалом показать их в TImage.
      Понимаю, что получить список изображений правильнее при помощи PHP скрипта, но в каком виде скрип должен вернуть данные, чтобы в Delphi получить из них массив не знаю.
      Раньше для получения изображений использовал такую процедуру. Но вопрос, где хранить изображения перед демонстрацией их в TImage? Создавать несколько MemoryStream?
      procedure LoadWebImage(url: string; image: TBitmap);
      var
        idhttp : TNetHTTPClient;
        ms : TMemoryStream;
      begin
       IdHTTP := TNetHTTPClient.Create(nil);
        ms := TMemoryStream.Create;
        try
          idhttp.Get(url, ms);
          ms.Position := 0;
          image.LoadFromStream(ms);
        finally
          ms.Free;
          idhttp.Free;
        end;
      end;
    • От denprox
      Доброго времени суток! Подскажите, как узнать оригинальный размер картинки, загруженной в TImage ?
    • От Vizit0r
      Delphi Seattle, Android 5.0.1
      Формирую картинку через ScanLine. На выходе полученный битмап рисуется на полотне TImage, на котором перед этим был нарисован Rect.
      GlobalBitmap - формированный tbitmap.
                 with ObjectPreviewImage.Bitmap.Canvas do             begin               BeginScene;               Clear(TAlphaColorRec.White);               DRect := TRectF.Create(0, 0, GlobalBitmap.Width + 8, GlobalBitmap.Height + 8);               DrawRect(DRect, 0, 0, AllCorners,                        StealthForm.ObjectPreviewImage.AbsoluteOpacity);               DRect := TRectF.Create(0, 0, GlobalBitmap.Width, GlobalBitmap.Height);               DrawBitmap(GlobalBitmap,DRect,                  TRectF.Create(2, 2, GlobalBitmap.Width + 2, GlobalBitmap.Height + 2), 1);               EndScene;             end;  
      Проблема собственно в чем - в андроидной версии слева и внизу рамка "съедается". В Win32 версии все отлично. На прилагаемых скриншотах это четко видно.
      Документацию читал, гугл гуглил.
       
      Что я делаю не так? Или это неизвестные подводные камни андроидного рисования на полотне?
       
      P.S. Картинка одинаковая, цвет к определенной области применяется не верно. Походу тоже андроидные приколы. Но с этим я уже разберусь.
      P.P.S. Уже разобрался с цветом - под андроидом Blue и Red в пикселе надо поменять местами. А насчет канвы - не получается никак.
      P

    • От Error
      *** Небольшой обмен опытом ***
      Вижу что вопросы о размере текста довольно частые, поделюсь своими наработками.
      function CalcTextSize(Text: string; Font: TFont; Size: Single = 0): TSizeF;
      Функция для расчета размера прямоугольника, занимаемого однострочным текстом.
      Параметры:
      Text - Текст Font - Шрифт с которым будет выводиться текст Size - если 0, то Font.Size будет использоваться из Font, иначе из данного параметра Исходный код:
      uses System.Types, FMX.Types, FMX.Graphics, FMX.TextLayout, System.Math, System.SysUtils; function CalcTextSize(Text: string; Font: TFont; Size: Single = 0): TSizeF; var TextLayout: TTextLayout; begin TextLayout := TTextLayoutManager.DefaultTextLayout.Create; try TextLayout.BeginUpdate; try TextLayout.Text := Text; TextLayout.MaxSize := TPointF.Create(9999, 9999); TextLayout.Font.Assign(Font); if not SameValue(0, Size) then begin TextLayout.Font.Size := Size; end; TextLayout.WordWrap := False; TextLayout.Trimming := TTextTrimming.None; TextLayout.HorizontalAlign := TTextAlign.Leading; TextLayout.VerticalAlign := TTextAlign.Leading; finally TextLayout.EndUpdate; end; Result.Width := TextLayout.Width; Result.Height := TextLayout.Height; finally TextLayout.Free; end; end;   function FontSizeForBox(Text: string; Font: TFont; Width, Height: Single; MaxFontSize: Single = cMaxFontSize): Integer;
      Функция возвращающая максимально возможный размер шрифта, для текста вписанного в заданный прямоугольник.
      Параметры:
      Text - Текст Font - Шрифт с которым будет выводиться текст Width, Height - Ширина и высота прямоугольника MaxFontSize - Максимально возможный размер шрифта Исходный код:
      uses System.Types, FMX.Types, FMX.Graphics, FMX.TextLayout, System.Math, System.SysUtils; const cMaxFontSize = 512; function FontSizeForBox(Text: string; Font: TFont; Width, Height: Single; MaxFontSize: Single = cMaxFontSize): Integer; var Size, Max, Min, MaxIterations: Integer; Current: TSizeF; begin Max := Trunc(MaxFontSize); Min := 0; MaxIterations := 20; repeat Size := (Max + Min) div 2; Current := CalcTextSize(Text, Font, Size); if ((Abs(Width - Current.Width) < 1) and (Width >= Current.Width)) and ((Abs(Height - Current.Height) < 1) and (Height >= Current.Height)) then break else if (Width < Current.Width) or (Height < Current.Height) then Max := Size else Min := Size; Dec(MaxIterations); until MaxIterations = 0; Result := Size; end; ---
      Также данные функции можно найти в этом юните
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...