Tumaso Опубликовано 16 августа, 2018 Поделиться Опубликовано 16 августа, 2018 Пользуюсь для отрисовки текста функцией Canvas.FillText. Но при выводе на канве текст получается немного размытым, особенно если сравнивать отображаемый текст с TLabel (тот же текст с теми же параметрами TFont у TLabel выглядит четче). Подскажите, как вывести текст без размытия? Цитата Ссылка на комментарий
0 ENERGY Опубликовано 16 августа, 2018 Поделиться Опубликовано 16 августа, 2018 (изменено) Значит он растягивается (если на Bitmap) или BitmapScale не тот. Покажите рабочий пример на PaintBox например.. Изменено 16 августа, 2018 пользователем ENERGY Цитата Ссылка на комментарий
0 Tumaso Опубликовано 16 августа, 2018 Автор Поделиться Опубликовано 16 августа, 2018 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 я не подумал, спасибо за подсказку Цитата Ссылка на комментарий
0 ENERGY Опубликовано 16 августа, 2018 Поделиться Опубликовано 16 августа, 2018 (изменено) Если на Timage то Image1.WrapMode := TImageWrapMode.Original; Чтобы не растягивало. Также обратите внимание на параметр BitmapScale. Он должен быть равен текущему scale, иначе изображение будет тоже искажено. var lScale: Single; lScreenService: IFMXScreenService; begin // FMX.Platform if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, lScreenService) then lScale := lScreenService.GetScreenScale else lScale := 1; Если у вас свой компонент от TControl , то там есть переменная Scene. и конструкция выше не нужна. Result := TBitmap.Create(Trunc(AWidth), Trunc(AHeight)); Result.BitmapScale := lScale; Есть одно но, если указать правильный Scale в Bitmap - то на Windows (если там scale > 1) часть рисунка на канве будет отрезаться, видимо какой то баг с просчетом координат с новым Scale в FMX, при это на мобильных системах все прекрасно работает и корректно рисуется и масштабируется с разными Scale. Я так рисую со сглаживанием через NativeDraw - сначала на Bitmap, для кэша, затем на канву. Возможно Ярослав знает в чем дело. Используйте этот метод BitmapScale на Android\iOS (рендер GlobalUseGPUCanvas := true; чтобы посмотреть на Win, но без сглаживания). Изменено 16 августа, 2018 пользователем ENERGY Anatoliy 1 Цитата Ссылка на комментарий
0 Tumaso Опубликовано 16 августа, 2018 Автор Поделиться Опубликовано 16 августа, 2018 Попробовал поиграться с BitmapScale, WrapMode, флагами GlobalXXXX - результат без изменений. Но что интересно - однострочный текст с помощью FillText выводится без искажений, аналогично TLabel (разницы не видно). Но вот если выводится текст, который переносится на две строки и более, то немного искажается во всех перепробованных вариантах. У меня как раз весь такой вывод текста занимает всегда больше 1 строки, и искажается. Попробовал для теста вывести в одну строчку - тогда все ок. Цитата Ссылка на комментарий
0 ENERGY Опубликовано 16 августа, 2018 Поделиться Опубликовано 16 августа, 2018 А если текст вывести на PaintBox для теста чтобы исключить Bitmap? Цитата Ссылка на комментарий
0 Tumaso Опубликовано 16 августа, 2018 Автор Поделиться Опубликовано 16 августа, 2018 На PaintBox что однострочный, что многострочный текст выводятся FillText-ом без искажений, чудеса) Цитата Ссылка на комментарий
0 Tumaso Опубликовано 16 августа, 2018 Автор Поделиться Опубликовано 16 августа, 2018 Соответственно в моей задаче решение понятно - генерирую изображение в paintbox, а уже из него переношу в Listview Цитата Ссылка на комментарий
0 ENERGY Опубликовано 16 августа, 2018 Поделиться Опубликовано 16 августа, 2018 (изменено) Значит Bitmap растягивается. Странно что WrapMode Original + BitmapScale не помог. Вы для каких платформ пишите? Scale какой возвращает система? Изменено 16 августа, 2018 пользователем ENERGY Цитата Ссылка на комментарий
0 Tumaso Опубликовано 16 августа, 2018 Автор Поделиться Опубликовано 16 августа, 2018 Проект для Android и iOS, wrapmode = original. Значение scale не смотрел, просто кодом присваивал. Да как то непонятно с этой растяжкой. Размеры я все проверил, всё идеально. Изображения и однострочный текст выводятся без проблем. Но если выводится текст с переносом (многострочный), так он выводится с размытием (я про текущую версию формирования Bitmap для ListView). У paintBox всё выводится как надо, поэтому тут какой то непонятный момент именно у FillText. Цитата Ссылка на комментарий
0 ENERGY Опубликовано 16 августа, 2018 Поделиться Опубликовано 16 августа, 2018 (изменено) Я бы на вашем месте сначала вывел текст в Timage.Bitmap, чтобы исключить другие направления. Если бы вы подготовили простой проект с этим багом, чтобы другие могли запустить, - было бы больше помощи. Т.к. у всех работа, и отвлекаться на создание нового проекта мало кому охота. Изменено 16 августа, 2018 пользователем ENERGY Цитата Ссылка на комментарий
0 Tumaso Опубликовано 17 августа, 2018 Автор Поделиться Опубликовано 17 августа, 2018 Так вы и так уже мне помогли с идеей решения проблемы Изначально я просто создавал TBitmap.Create, выводил в него текст и копировал полученный буфер в элемент ListView. При многострочном тексте получался эффект размытого текста. Я немного переписал код, теперь создаю TPaintBox.Create, вывожу текст в него и копирую этот буфер в TListView, теперь все ок Цитата Ссылка на комментарий
0 ENERGY Опубликовано 17 августа, 2018 Поделиться Опубликовано 17 августа, 2018 Вы же копируете c PaintBox на Bitmap (буфер)? Цитата Ссылка на комментарий
0 Tumaso Опубликовано 17 августа, 2018 Автор Поделиться Опубликовано 17 августа, 2018 да, копирую. bitmap копируется без изменений Цитата Ссылка на комментарий
0 ENERGY Опубликовано 17 августа, 2018 Поделиться Опубликовано 17 августа, 2018 (изменено) А как вы его копируете? MakeScreenshot? Изменено 17 августа, 2018 пользователем ENERGY Цитата Ссылка на комментарий
0 Tumaso Опубликовано 17 августа, 2018 Автор Поделиться Опубликовано 17 августа, 2018 ENERGY, копирую с помощью DrawBitmap DrawBitmap( ASource, AlignToPixel(ARect), AlignToPixel(TRectF.Create(0, 0, AWidth, AHeight)), 1, False ); Цитата Ссылка на комментарий
0 dnekrasov Опубликовано 17 августа, 2018 Поделиться Опубликовано 17 августа, 2018 (изменено) 19 минут назад, Tumaso сказал: ENERGY, копирую с помощью DrawBitmap DrawBitmap( ASource, AlignToPixel(ARect), AlignToPixel(TRectF.Create(0, 0, AWidth, AHeight)), 1, False ); 1. Уберите AlignToPixel - здесь он не нужен 2. Попробуйте поставить вместо False - True в последнем параметре. 3. Проверьте идентичность ARect.Width, ARect.Height и AWidth, AHeight Изменено 17 августа, 2018 пользователем dnekrasov Цитата Ссылка на комментарий
0 Tumaso Опубликовано 17 августа, 2018 Автор Поделиться Опубликовано 17 августа, 2018 Так я же уже решил проблему, путем построения промежуточного буфера в TPaintBox вместо TBitmap, теперь многострочный текст не искажается... Цитата Ссылка на комментарий
-1 dnekrasov Опубликовано 17 августа, 2018 Поделиться Опубликовано 17 августа, 2018 1 час назад, Tumaso сказал: Так я же уже решил проблему, путем построения промежуточного буфера в TPaintBox вместо TBitmap Просто какая-то странная проблема, впрочем как и её решение. Я FillText использую довольно активно, но никогда ничего подобного не наблюдал. Да и что-то мне подсказывает что дело совсем не в том, что надо использовать в качестве буфера TPaintBox вместо TBitmap. Ведь у людей, которые прочитают эту ветку форума может сложиться не правильное мнение, как надо решать подобные проблемы. ENERGY 1 Цитата Ссылка на комментарий
0 ENERGY Опубликовано 17 августа, 2018 Поделиться Опубликовано 17 августа, 2018 (изменено) Автор, мне кажется, если бы вы прикрепили пример проекта, где баг воспроизводится (напр на TImage.Bitmap), было бы больше помощи, втч и тем кто будет спрашивать в будущем об этом. Ваше решение не добавит производительности программе, тем более вы используете это для каждого Item в списке. Изменено 17 августа, 2018 пользователем ENERGY Цитата Ссылка на комментарий
0 Tumaso Опубликовано 17 августа, 2018 Автор Поделиться Опубликовано 17 августа, 2018 59 минут назад, dnekrasov сказал: Просто какая-то странная проблема, впрочем как и её решение. Я FillText использую довольно активно, но никогда ничего подобного не наблюдал. Да и что-то мне подсказывает что дело совсем не в том, что надо использовать в качестве буфера TPaintBox вместо TBitmap. Ведь у людей, которые прочитают эту ветку форума может сложиться не правильное мнение, как надо решать подобные проблемы. Если бы не было этой проблемы, я бы ее и не спрашивал бы, как с ней бороться. Суть в том, что я использую TListView с динамической высотой элементов (высота может быть различной) и динамической формированием элементов. В качестве шрифта используется устанавливаемый с приложением шрифт (если быть точным - plumb). Изначально я формировал изображение, рисуя на Bitmap у ListView.ItemAppearance.Item.TImageObjectAppearance. В данной ситуации FillText при выводе теста, содержащего больше одной строки, приводил к формированию текста с небольшим искажением, но при этом текст в одну строку выводится без проблем. В качестве решения я использовал формирование в промежуточном буфере на базе TPaintBox, после чего копировал сформированное изображение в Bitmap. Искажения текста исчезли. Почему в исходном варианте наблюдается такое поведение FillText, я не знаю. Все scales, width / height и т.д. рассчитываются верно. Поэтому предлагаю лично вам свое мнение об этой проблеме и способах ее решения либо оставить при себе, либо озвучивать в другой теме. Желаете, что бы я начал комментировать ваши рассуждения об использовании FMX на этом форуме? )))))))))) Сразу отвечаю на замечание ENERGY - формируемые изображения кэшируются, ListView заполняется в коде очень быстро, и также шустро работает, скролится без лагов. Для пользователей программы это важно, по моему скромному мнению. Цитата Ссылка на комментарий
0 ENERGY Опубликовано 25 августа, 2018 Поделиться Опубликовано 25 августа, 2018 (изменено) Проблема в том что ваш битмап растягивается ,т.к. у него не правильный масштаб (масштаб 1, а нужен системный который больше). Значит 1. Получите текущий Scale из системы (если отнаследовались от TControl, то есть Scene.GetSceneScale). 2. Установите правильный размер у битмапа - Bitmap.SetSize(Ceil(Width * Scale), Ceil(Height * Scale)) Вместо Ceil можно Trunc попробовать, что лучше. BitmapScale не трогайте (его нужно менять, если рисуете векторный Path ). Теперь попробуйте вывести на него текст, а затем этот битпам отобразить на PaintBox. Должно все получиться с высокой вероятность, я так отрисовываю примитивы, напр. круг через китайский модуль NativeAPI, чтобы было сглаживание на Android/iOS. Изменено 25 августа, 2018 пользователем ENERGY Anatoliy 1 Цитата Ссылка на комментарий
0 Tumaso Опубликовано 26 августа, 2018 Автор Поделиться Опубликовано 26 августа, 2018 @ENERGY, я сделал вывод текста в tpaintbox, после чего копирую полученный битмап в TListView, искажения текста ушли. Почему прямое рисование искажает, я пока не понял - вроде все коэффициенты и размеры один к одному. Так что уже неактуально. А вот насчет рисования кругов со сглаживанием через nativeAPI, можно поподробнее? А то TCircle в андроиде это полный треш Цитата Ссылка на комментарий
0 ENERGY Опубликовано 26 августа, 2018 Поделиться Опубликовано 26 августа, 2018 (изменено) 4 часа назад, Tumaso сказал: А вот насчет рисования кругов со сглаживанием через nativeAPI, можно поподробнее? А то TCircle в андроиде это полный треш Native Api (google translate ) : https://github.com/OneChen/FMXNativeDraw (там же ссылка на описаниеl) Равиль сделал на основе этого модуля готовые компоненты: https://github.com/rzaripov1990/ZMaterialComponents Изменено 26 августа, 2018 пользователем ENERGY Anatoliy и Tumaso 1 1 Цитата Ссылка на комментарий
Вопрос
Tumaso
Пользуюсь для отрисовки текста функцией Canvas.FillText. Но при выводе на канве текст получается немного размытым, особенно если сравнивать отображаемый текст с TLabel (тот же текст с теми же параметрами TFont у TLabel выглядит четче).
Подскажите, как вывести текст без размытия?
Ссылка на комментарий
23 ответа на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.