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

Tumaso

Пользователи
  • Постов

    331
  • Зарегистрирован

  • Посещение

  • Победитель дней

    39

Весь контент Tumaso

  1. Если бы не было этой проблемы, я бы ее и не спрашивал бы, как с ней бороться. Суть в том, что я использую TListView с динамической высотой элементов (высота может быть различной) и динамической формированием элементов. В качестве шрифта используется устанавливаемый с приложением шрифт (если быть точным - plumb). Изначально я формировал изображение, рисуя на Bitmap у ListView.ItemAppearance.Item.TImageObjectAppearance. В данной ситуации FillText при выводе теста, содержащего больше одной строки, приводил к формированию текста с небольшим искажением, но при этом текст в одну строку выводится без проблем. В качестве решения я использовал формирование в промежуточном буфере на базе TPaintBox, после чего копировал сформированное изображение в Bitmap. Искажения текста исчезли. Почему в исходном варианте наблюдается такое поведение FillText, я не знаю. Все scales, width / height и т.д. рассчитываются верно. Поэтому предлагаю лично вам свое мнение об этой проблеме и способах ее решения либо оставить при себе, либо озвучивать в другой теме. Желаете, что бы я начал комментировать ваши рассуждения об использовании FMX на этом форуме? )))))))))) Сразу отвечаю на замечание ENERGY - формируемые изображения кэшируются, ListView заполняется в коде очень быстро, и также шустро работает, скролится без лагов. Для пользователей программы это важно, по моему скромному мнению.
  2. Так я же уже решил проблему, путем построения промежуточного буфера в TPaintBox вместо TBitmap, теперь многострочный текст не искажается...
  3. Android SDK 25.2.5 AndroidManifest.template.xml: <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="26" /> Phones: Samsung Galaxy S3, S4, S5, S6, S7, S8 Samsung Note 3, 4, 5
  4. ENERGY, копирую с помощью DrawBitmap DrawBitmap( ASource, AlignToPixel(ARect), AlignToPixel(TRectF.Create(0, 0, AWidth, AHeight)), 1, False );
  5. Alisson R Oliveira, required permissions for TakeImageFromLibrary: READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE. I use TakeImageFromLibrary only on android 5+, because on android 4.x application with TakeImageFromLibrary may crash any time. required permission for TakePhotoFromcamera and TCameraComponent: CAMERA
  6. да, копирую. bitmap копируется без изменений
  7. Work with camera: interface type TMyForm = class(TForm) { ... } Image1: TImage; Image2: TImage; Camera1: TCameraComponent; Camera2: TCameraComponent; RectangleCamera1On: TRectangle; RectangleCamera1Off: TRectangle; RectangleCamera2On: TRectangle; RectangleCamera2Off: TRectangle; { ... } procedure FormCreate(Sender: TObject); { ... } procedure Camera1SampleBufferReady(Sender: TObject; const ATime: TMediaTime); procedure Camera2SampleBufferReady(Sender: TObject; const ATime: TMediaTime); procedure Camera1OnClick(Sender: TObject); procedure Camera1OffClick(Sender: TObject); procedure Camera2OnClick(Sender: TObject); procedure Camera2OffClick(Sender: TObject); { ... } private { ... } procedure RetrieveCamera1Image; procedure RetrieveCamera2Image; { ... } end; implementation procedure TMyForm.FormCreate(Sender: TObject); begin RectangleCamera1On.OnClick := Camera1OnClick; RectangleCamera1Off.OnClick := Camera1OffClick; RectangleCamera2On.OnClick := Camera2OnClick; RectangleCamera2Off.OnClick := Camera2OffClick; Camera1.OnSampleBufferReady := Camera1SampleBufferReady; Camera1.Kind := TCameraKind.FrontCamera; Camera2.OnSampleBufferReady := Camera2SampleBufferReady; Camera2.Kind := TCameraKind.BackCamera; end; procedure TMyForm.Camera1SampleBufferReady(Sender: TObject; const ATime: TMediaTime); begin TThread.Synchronize(TThread.CurrentThread, RetrieveCamera1Image); end; procedure TMyForm.Camera2SampleBufferReady(Sender: TObject; const ATime: TMediaTime); begin TThread.Synchronize(TThread.CurrentThread, RetrieveCamera2Image); end; procedure TMyForm.Camera1OnClick(Sender: TObject); begin Camera1.Active := True; end; procedure TMyForm.Camera1OffClick(Sender: TObject); begin Camera1.Active := False; end; procedure TMyForm.Camera2OnClick(Sender: TObject); begin Camera2.Active := True; end; procedure TMyForm.Camera2OffClick(Sender: TObject); begin Camera2.Active := False; end; procedure TMyForm.RetrieveCamera1Image; var LBitmap: TBitmap; LScaleXY: Double; LScale: Double; LWidth: Double; LSource: TRectF; begin if Image1.Height > 0 then LScaleXY := Image1.Width / Image1.Height else LScaleXY := 1; try LBitmap := TBitmap.Create; try Camera1.SampleBufferToBitmap(LBitmap, True); if (LBitmap.Width > 0) and (LBitmap.Height > 0) then begin LScale := LBitmap.BitmapScale / Image1.Bitmap.BitmapScale; LWidth := LBitmap.Height * LScaleXY; LSource := TRectF.Create((LBitmap.Width - LWidth) / 2, 0, LWidth + (LBitmap.Width - LWidth) / 2, LBitmap.Height); with Image1.Bitmap do begin SetSize(Round(Image1.Width), Round(Image1.Height)); if Canvas.BeginScene then begin try Canvas.DrawBitmap( LBitmap, Canvas.AlignToPixel(LSource), Canvas.AlignToPixel(TRectF.Create(0, 0, Width * LScale, Height * LScale)), 1, False ); finally Canvas.EndScene; end; end; end; end; finally LBitmap.DisposeOf; end; except { some code } end; end; procedure TMyForm.RetrieveCamera2Image; var LBitmap: TBitmap; LScaleXY: Double; LScale: Double; LWidth: Double; LSource: TRectF; begin if Image2.Height > 0 then LScaleXY := Image2.Width / Image2.Height else LScaleXY := 1; try LBitmap := TBitmap.Create; try Camera2.SampleBufferToBitmap(LBitmap, True); if (LBitmap.Width > 0) and (LBitmap.Height > 0) then begin LScale := LBitmap.BitmapScale / Image2.Bitmap.BitmapScale; LWidth := LBitmap.Height * LScaleXY; LSource := TRectF.Create((LBitmap.Width - LWidth) / 2, 0, LWidth + (LBitmap.Width - LWidth) / 2, LBitmap.Height); with Image2.Bitmap do begin SetSize(Round(Image2.Width), Round(Image2.Height)); if Canvas.BeginScene then begin try Canvas.DrawBitmap( LBitmap, Canvas.AlignToPixel(LSource), Canvas.AlignToPixel(TRectF.Create(0, 0, Width * LScale, Height * LScale)), 1, False ); finally Canvas.EndScene; end; end; end; end; finally LBitmap.DisposeOf; end; except { some code } end; end;
  8. Так вы и так уже мне помогли с идеей решения проблемы Изначально я просто создавал TBitmap.Create, выводил в него текст и копировал полученный буфер в элемент ListView. При многострочном тексте получался эффект размытого текста. Я немного переписал код, теперь создаю TPaintBox.Create, вывожу текст в него и копирую этот буфер в TListView, теперь все ок
  9. Проект для Android и iOS, wrapmode = original. Значение scale не смотрел, просто кодом присваивал. Да как то непонятно с этой растяжкой. Размеры я все проверил, всё идеально. Изображения и однострочный текст выводятся без проблем. Но если выводится текст с переносом (многострочный), так он выводится с размытием (я про текущую версию формирования Bitmap для ListView). У paintBox всё выводится как надо, поэтому тут какой то непонятный момент именно у FillText.
  10. Android/iOS не даст запустить одновременно 2 и более диалогов выбора изображений из библиотеки. Поэтому задача тривиальна - перед вызовом TakeImageFromLibrary запоминаешь TImage (любым способом), в которое нужно будет занести изображение. А в ApplyImage по сохраненному значению определяешь, в какой TImage заносить. По получению изображения из камеры - тут нужно использовать TCameraComponent (работает стабильно).
  11. Соответственно в моей задаче решение понятно - генерирую изображение в paintbox, а уже из него переношу в Listview
  12. На PaintBox что однострочный, что многострочный текст выводятся FillText-ом без искажений, чудеса)
  13. Попробовал поиграться с BitmapScale, WrapMode, флагами GlobalXXXX - результат без изменений. Но что интересно - однострочный текст с помощью FillText выводится без искажений, аналогично TLabel (разницы не видно). Но вот если выводится текст, который переносится на две строки и более, то немного искажается во всех перепробованных вариантах. У меня как раз весь такой вывод текста занимает всегда больше 1 строки, и искажается. Попробовал для теста вывести в одну строчку - тогда все ок.
  14. function MakeItemImage(const AWidth, AHeight: Double; const ALabel: TLabel): TBitmap; begin Result := TBitmap.Create(Trunc(AWidth), Trunc(AHeight)); with Result.Canvas do begin if BeginScene then begin try Clear(TAlphaColorRec.Null); // текст Font.Assign(ALabel.Font); Fill.Color := ALabel.FontColor; FillText( TRectF.Create(0, 0, Result.Width, Result.Height), ALabel.Text, True, 1, [], TTextAlign.Leading, TTextAlign.Center ); finally EndScene; end; end; end; end; Этот метод вызывается для формирования изображения для элемента в TListView (по событию OnUpdateObjects, режим DynamicAppearance). Вроде все элементарно, но текст немного искажен. Но вот насчет возможного растягивания этого сформированного изображения в ListView я не подумал, спасибо за подсказку
  15. Пример моего кода: interface type TMyForm = class(TForm) { ... } procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); {$IFDEF ANDROID} procedure ImageFileMessageListener(const Sender: TObject; const M: TMessage); {$ENDIF} {$IFDEF IOS} procedure ImageFileFinish(Image: TBitmap); {$ENDIF} procedure ImageFromLibraryClick(Sender: TObject); { ... } private { ... } procedure ApplyImage(Image: TBitmap); { ... } end; implementation procedure TMyForm.FormCreate(Sender: TObject); begin {$IF DEFINED(ANDROID)} TMessageManager.DefaultManager.SubscribeToMessage(TMessageDidFinishTakingImageFromLibrary, ImageFileMessageListener); {$ENDIF} end; procedure TMyForm.FormDestroy(Sender: TObject); begin {$IF DEFINED(ANDROID)} TMessageManager.DefaultManager.Unsubscribe(TMessageDidFinishTakingImageFromLibrary, ImageFileMessageListener, True); {$ENDIF} end; {$IFDEF ANDROID} procedure TMyForm.ImageFileMessageListener(const Sender: TObject; const M: TMessage); begin try if M is TMessageDidFinishTakingImageFromLibrary then ApplyImage(TMessageDidFinishTakingImageFromLibrary(M).Value); except { code for exception handle } end; end; {$ENDIF} {$IFDEF IOS} procedure TMyForm.ImageFileFinish(Image: TBitmap); begin try ApplyImage(Image); except { code for exception handle } end; end; {$ENDIF} procedure TMyForm.ImageFromLibraryClick(Sender: TObject); {$IF DEFINED(ANDROID) OR DEFINED(IOS)} var LImageService: IFMXTakenImageService; LImageParams: TParamsPhotoQuery; {$ENDIF} begin if TPlatformServices.Current.SupportsPlatformService(IFMXTakenImageService, IInterface(LImageService)) then begin LImageParams.RequiredResolution := TSize.Create(1024, 1024); LImageParams.Editable := False; LImageParams.NeedSaveToAlbum := False; // под Android обработчик OnDidFinishTaking указывать нельзя, т.к. это может привести к рестарту программы // см. http://docwiki.embarcadero.com/Libraries/Berlin/en/FMX.MediaLibrary.TMessageDidFinishTakingImageFromLibrary LImageParams.OnDidFinishTaking := {$IFDEF IOS}ImageFileFinish{$ELSE}nil{$ENDIF}; LImageParams.OnDidCancelTaking := nil; LImageService.TakeImageFromLibrary({$IFDEF IOS}ImageFile{$ELSE}nil{$ENDIF}, LImageParams); end else raise Exception.Create('No image library access'); end; procedure TMyForm.ApplyImage(Image: TBitmap); begin { code for received image } end;
  16. Пользуюсь для отрисовки текста функцией Canvas.FillText. Но при выводе на канве текст получается немного размытым, особенно если сравнивать отображаемый текст с TLabel (тот же текст с теми же параметрами TFont у TLabel выглядит четче). Подскажите, как вывести текст без размытия?
  17. Embarcadero wiki: http://docwiki.embarcadero.com/Libraries/Berlin/en/FMX.MediaLibrary.TMessageDidFinishTakingImageFromLibrary
  18. Tumaso

    IOS: Exception class 6

    Ха, некоторые до сих пор на 4s сидят))
  19. Tumaso

    Лайки

    Вообще Ярослав ведь FGX native занимается, так что думаю - не должно стать ему неинтересно
  20. Tumaso

    Доступ к COM порту

    У WinSoft (http://www.winsoft.sk) есть компоненты для работы с com-портами в андроиде. Либа платная, тем не менее вашу задачу решает.
  21. Tumaso

    Баг в Tokio

    Это в 10.2.3?
  22. Tumaso

    Баг в Tokio

    у меня в 10.2.3 работает нормально в берлине не работало, приходилось извращаться между потоками и основным потоком
  23. gelo1 Вот если честно, над интерфейсом вам нужно усиленно поработать в плане редизайна. Кнопки управления расположены неудачно, цветовая тема лично меня напрягает, не используется вся доступная область на экране.
  24. Абсолютно неправильное понимание. Гугл анализирует minSdkVersion и targetSdkVersion не для того, чтобы запрещать публикацию apk в google play, а для того, чтобы: 1. ограничить установку apk на устройства с sdk, меньшей чем minSdkVersion - т.е. если например minSdkVersion="18", то на Android ниже 4.3 гугл плей не даст установить 2. использовать на устройстве sdk наиболее приближенной к targetSdkVersion (но не превышая) - т.е. если например targetSdkVersion="23", то на Android 4.3 будет использовать sdk 18, на android 8.1 - sdk 23
  25. На винде много примеров реализации таймеров, выдающих дискретность 1 мс. Навскидку - у либы с glscene.org есть подобный таймер, банально сделан через отдельный поток, так что можно обойтись без тюнинга ОС
×
×
  • Создать...