WPF Размытые шрифты - Решения

153

Проблема описана и продемонстрирована по следующим ссылкам:

Пояснение: Ясность текста в WPF . Эта ссылка имеет сравнение шрифтов.

Я хотел бы собрать все возможные решения для этой проблемы. Microsoft Expression Blend использует WPF, но шрифты выглядят читабельно.

  • Темный фон, как в Microsoft Expression Blend
  • Увеличение размера шрифта и изменение шрифта (Calibri ...) [ссылка]
  • Вставить формы окна [ссылка]
  • Используйте класс GDI + и / или Windows Forms TextRenderer, чтобы отобразить текст в растровом изображении, а затем отобразить это растровое изображение в качестве элемента управления WPF. [ссылка на сайт]

Есть еще решения?

Это будет исправлено в бета-версии 2 VS2010 (и WPF4)

ЭТО СМОТРИТ, КАК ЭТО ПОЛНОСТЬЮ РЕШЕНО!

ComputerZen.com Скотта Хансельмана: WPF и текстовое размытие, теперь с полной ясностью

Роберт Вукович
источник
VS2010RC совершенно непригоден для меня mpdreamz.nl/vs2010RC-blur.png
Мартейн Лаарман
VS2010RC на моей машине выглядит намного лучше, чем на вашей картинке, на самом деле с белым фоном очень хорошо, но все же отстой на темном фоне.
Роберт Вукович
Нашли ли вы какое-либо решение для этой проблемы, На самом деле у меня есть та же проблема здесь, в моем приложении, и я использую WPF 3.5 с VS2010
SharpUrBrain
Последние 3 ссылки мертвы.
SHIN JaeGuk

Ответы:

107

Техническое образование

Подробная статья о рендеринге текста WPF от одного из менеджеров текстовых программ WPF на windowsclient.net: Четкость текста в WPF .

Проблема сводится к тому, что WPF нужен линейно масштабируемый рендерер шрифтов для плавной анимации. Pure ClearType, с другой стороны, занимает немного свободы с шрифтом, чтобы выдвигать вертикальные основы в следующий пиксель.

Разница очевидна, если сравнивать классический «каскадный» рисунок. WinForms в нижней левой части, WPF в верхней правой части:

Хотя я и не фанат особенностей рендеринга шрифтов в WPF, я могу представить шум, если анимации будут прыгать, как в каскаде Winforms.

Игра с реестром

Особый интерес для меня представляла ссылка на статью MSDN « Настройки реестра ClearType », в которой объясняются возможные пользовательские настройки реестра:

  • Уровень ClearType: количество хинтинга субпикселя
  • Уровень гаммы
  • Структура пикселя: как расположены цветные полосы в пикселе дисплея
  • Уровень контрастности текста: регулирует ширину глиф стеблей, чтобы сделать шрифт тяжелее

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

Другой подход

Лучший совет, который дала статья Text Clarity, - это увеличение размера шрифта и изменение шрифта. Calibri работает для меня лучше, чем стандартный пользовательский интерфейс Segoe. Из-за его популярности в качестве веб-шрифта, я тоже попробовал Verdana, но он имеет неприятный скачок в весе между 14pt и 15pt, что очень заметно при анимации размера шрифта.

WPF 4.0

В WPF 4 будет улучшена поддержка влияния на рендеринг шрифтов. В текстовом блоге WPF есть статья, объясняющая изменения. Наиболее заметно, что теперь есть (по крайней мере) три различных типа рендеринга текста:

сравнение рендеринга текста

<grumble> Этого должно быть достаточно для каждого дизайнера. </ grumble>

Дэвид Шмитт
источник
11
отличное объяснение +1. Вероятно, объясняет, почему во Flash такой ужасный рендеринг.
Джефф Этвуд
1
Да. Это хорошее объяснение, но я все еще хотел бы, чтобы был способ включить подсказку шрифта для красивого вида, когда вы знаете, что не собираетесь анимировать. Я полагаю, что это подразумевает определенный масштаб, для которого вы оптимизируете подсказку. Подобные вещи заставляют WPF казаться мне все еще бета-версией.
PeterAllenWebb
Это не то, что «масштабируемый» вариант не использует подсказки шрифтов, просто WPF не оптимизирует попадание в пиксельную сетку, как это делает ClearType. Возможно SnapToDevicePixels должен работать для текста, но это всегда должно быть унаследовано, потому что элемент управления не может знать, может ли он привязываться или нет.
Дэвид Шмитт
2
Особенно актуальным является вложенное свойство TextOptions.TextFormattingMode ( msdn.microsoft.com/en-us/library/ee169597.aspx ). WPF4 и Silverlight также имеют свойства UseLayoutRounding ( msdn.microsoft.com/en-us/library/dd783605.aspx ) и SnapsToDevicePixels ( msdn.microsoft.com/en-us/library/… ).
Пэт
@All: я не могу найти способ отключить сглаживание текста в WPF3.5, и в результате текст метки или кнопки выглядит действительно плохо. В идеале я хотел бы отключить сглаживание глобально для шрифтов. Как я могу сделать это?
SharpUrBrain
128

В .NET 4 наконец-то есть решение для низкого качества рендеринга текста в WPF, но оно хорошо скрыто. Установите следующее для каждого окна:

TextOptions.TextFormattingMode="Display"

Значением по умолчанию является «Идеально», что совсем не то, что подразумевает название.

В TextOptions есть два других параметра, а именно TextHintingMode и TextRenderingMode, но оба имеют разумные значения по умолчанию.

Хельге Кляйн
источник
Все. Спасибо. Это помогает мне решить проблему, но вам нужно только определить это один раз в контейнере, как <grid>
Peter Du
Да, и если вы установите его в окне, оно действительно для всего, что содержится в этом окне.
Хельге Кляйн
Потратил много времени на поиски этого на тоннах сайтов и блогов, которые рассказывают о том, насколько лучше форматирование текста в VS2010 RTM / .Net 4 (я согласен, это так!). Но никто из них не хотел упоминать, как вы можете создавать WPF-приложения, которые вы создаете с его помощью. Почему это свойство так хорошо скрыто? Большое спасибо.
М-Перор
5
Все, что я хочу, это! Мне действительно все равно, насколько сложен рендеринг WPF, шрифты просто неприемлемы для всех.
Джерри Лян
1
У меня работает «Идеал», а не «Дисплей». Проект на .NET 4.6.2. Может быть, они исправили запутанное имя.
Джо
40

Я столкнулся с проблемой на днях, когда использовал границу, к которой применен эффект DropShadowEffect . В результате весь текст внутри этой границы был очень размытым. Не имеет значения, был ли текст внутри других панелей или непосредственно под границей - любой текстовый блок, являющийся дочерним по отношению к родительскому элементу, к которому применен эффект, похоже, подвержен влиянию.

Решение этого конкретного случая состояло в том, чтобы не помещать вещи внутри границы, которая имеет эффекты, а вместо этого использовать сетку (или что-либо еще, что поддерживает размещение контента друг над другом) и поместить прямоугольник в ту же ячейку, что и текст (т.е. как родной брат в визуальном дереве) и наложить эффекты на это.

Вот так:

<!-- don't do this --->
<Border>
     <Border.Effect>
          <DropShadowEffect BlurRadius="25" ShadowDepth="0" Opacity="1"/>
     </Border.Effect>
     <TextBlock Text="This Text Will Be Blurry" />
</Border>

<!-- Do this instead -->
<Grid>
  <Rectangle>
     <Rectangle.Effect>
          <DropShadowEffect BlurRadius="25" ShadowDepth="0" Opacity="1"/>
     </Rectangle.Effect>
  </Rectangle>
  <TextBlock Text="This Text Will Be Crisp and Clear" />
</Grid>
Исак Саво
источник
Это хорошо сработало. Немного хак, но лучше, чем возиться с настройками и т. Д. Хороший. Спасибо. Тем не менее, я должен был установить заполнение прямоугольника. Может быть, это была только моя установка, хотя.
Гадес
Да, вы правы. Прямоугольник по умолчанию прозрачен, что делает тень очень странной.
Исак Саво
этого не происходит в моем примере приложения, я использую WPF 3.5
SharpUrBrain,
@SharpUrBrain: что не происходит? Это все еще размыто даже после использования моего второго примера?
Исак Саво
Да, все еще размыто после использования вашего второго примера
SharpUrBrain,
10

Это будет исправлено в бета-версии 2 VS2010 (и WPF4):

Павел Минаев
источник
1
+1 за тестирование. Интересно посмотреть, насколько шире этот текст.
Дэвид Шмитт
6

SnapToDevicePixels применяется только к фигурам WPF (линии и т. Д.), А не к средству визуализации текста.

Нет известного решения этой проблемы. По словам Microsoft, поведение «нарочно».

Также посмотрите эту ветку на форумах Microsoft, где обсуждаются проблемы - она ​​получила несколько ответов от MS, которые разъясняют их позицию по этому вопросу.


источник
Исправлено в WPF 4 с использованием присоединенного свойства TextOptions.TextFormattingMode ( msdn.microsoft.com/en-us/library/ee169597.aspx ).
Пэт
1
Имя свойства - «SnapsToDevicePixels», а не «SnapToDevicePixels», как написано.
Нир Корнфельд
6

С точки зрения разработчика, единственным известным «обходным путем» на сегодняшний день является использование класса GDI + и / или Windows Forms TextRenderer для отображения текста в растровом изображении, а затем визуализация этого растрового изображения в качестве элемента управления WPF. Помимо очевидных последствий для производительности, это не облегчает проблему для существующих приложений.

Теперь я создал билет Microsoft Connect для этой проблемы (к моему удивлению, несмотря на все негативы, в указанном трекере не было реального сообщения об ошибке).

Поскольку это один из официальных каналов передачи запросов и вопросов в Microsoft, я бы посоветовал также перейти к нему для более быстрого ответа. По крайней мере, если вы хотите, чтобы проблема была решена тем или иным образом, голосование за этот билет и / или подтверждение проблемы помогут привлечь внимание руководителей и инженеров Microsoft к этой проблеме и, возможно, повысить ее предполагаемый приоритет.

Дэвид Шмитт
источник
6

Я не считаю это ошибкой, но конфигурация по умолчанию действительно очень раздражает. Вот сравнение всех комбинаций

TextOptions.TextRenderingMode
TextOptions.TextFormattingMode
RenderOptions.ClearTypeHint

SnapToDevicePixels не делает различий в рендеринге текста.

http://i.stack.imgur.com/cS3S2.png

Я предпочитаю:

TextOptions.TextRenderingMode="Auto"
TextOptions.TextFormattingMode="Ideal"
RenderOptions.ClearTypeHint="Auto"

где вертикальные линии никогда не размыты.

Используется шрифт Open Sans Light, который может быть очень красивым, если он хорошо используется, как в последней версии TeamViewer.

Для тех, кто использует Mahapps.Metro, проблема заключается в TransitioningContentControl https://github.com/MahApps/MahApps.Metro/issues/889

Габриель
источник
4

Только что опробовал бета-версию VS2010, которая делается в WPF, и она страдает от проблемы размытых шрифтов. Особенно на подсказках.

Это, кажется, дает некоторые доказательства того, что WPF4 на самом деле не решит проблему (если что-то выглядит хуже)

Орион Эдвардс
источник
3
Я регистрирую ошибки против VS2010B1 для каждого места в пользовательском интерфейсе, текст размыт. Подсказки почти комично плохие, я согласен. Учитывая, как явно было сказано, что это должно было быть исправлено в WPF4, я могу только надеяться, что он просто не попал в эту бета-версию.
Уилл Дин
4

Вау, я не могу поверить, что наконец-то получил свои WPF-шрифты для чтения И я также не могу поверить, что нет диалогового окна параметров, чтобы сделать эти изменения легкими, в то время как значения по умолчанию ужасны на моем дисплее.

Эти настройки реестра (в десятичном формате) работают для меня и наиболее близки к моему обычному шрифту cleartype:

  • ClearTypeLevel: 10 (в основном псевдонимы в оттенках серого)
  • GammaLevel: 1300 (более высокая гамма сделала шрифт слишком тонким, и я видел цвета в псевдонимах)
VVS
источник
3

Они говорят, что «SnapToDevicePixels = true» работает, но я никогда не видел хороших результатов.

Я борюсь с размытым текстом, переключаясь на другой шрифт.

Очевидно, что это не решение проблемы, однако именно так я и обошел эту проблему.

Инишир
источник
Я только что сравнил TextBlock с SnapToDevicePixels = "true" с одним без, и не было никакой разницы с шрифтом Segoe UI в 12duis. Могу я спросить, какие шрифты вы используете?
Дэвид Шмитт
Мы также улучшили ситуацию, переключив наш шрифт. Мы выбрали шрифт Avenir (я не думаю, что он установлен по умолчанию, по крайней мере, не в Windows XP).
cplotts
0

Если вы предпочитаете использовать базовый класс C # для настройки окон для вашего приложения (или у вас есть для этого причина), вот как вы можете настроить форматирование текста для использования привлекательного режима отображения:

public class SnappyWindow : Window
{
    public SnappyWindow()
    {
        SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
    }
}
Эдвард Брей
источник