TextRenderer основан на GDI, а Graphics.DrawString основан на GDI+. Именно эти функции могут предоставлять более качественный текст при рисовании текста на изображении.
Graphics.DrawString vs TextRenderer.DrawText, который может обеспечить лучшее качество
Ответ 1
Только мои 2 цента: я всегда использую Graphics.DrawString, за исключением случаев, когда мне нужно делать обычную роспись для моих (Windows Forms) элементов управления. Например, в списке, в котором установлен OwnerDraw, если я присоединяю обработчик события DrawItem, который полностью рисует элементы, включая текст элемента. Или в пользовательском контроле я должен рисовать себя.
В приложении, использующем Visual Styles для ОС, которое поддерживает его, и оно включено, текст, нарисованный графикой. DrawString выглядит "выключен" по сравнению с обычным текстом, нарисованным другими элементами управления. Похоже, что это происходит из-за различий в методе "ClearType" (или нет), хотя я не уверен, и у меня нет документов, чтобы поддержать этот вывод. (Это похоже на то, как текст делался на .Net 1.x или при переключении FlatStyle от стандарта к системе и v.v.)
В таких случаях только (текстовое рисование на элементах Winforms) я использую TextRenderer.DrawText, чтобы текст лучше сочетался с другими элементами управления.
Если "смешение с туземцами" не является одной из ваших проблем (как это выглядит, поскольку вы хотите нарисовать изображение), я бы пошел на Graphics.DrawString. Кроме того, если вы хотите печатать, вы должны, поскольку TextRenderer работает только на экране (не на холсте принтера).
Ответ 2
Я собираюсь перекрестить свой ответ с здесь, просто чтобы информация обходилась.
Существует два способа рисования текста в .NET:
- GDI + (
graphics.MeasureString
иgraphics.DrawString
) - GDI (
TextRenderer.MeasureText
иTextRenderer.DrawText
)
В .NET 1.1 все использовалось GDI + для рендеринга текста. Но были некоторые проблемы:
- Возникают некоторые проблемы с производительностью, вызванные несколько безгражданностью GDI +, где будут установлены контексты устройств, а затем оригинал, восстановленный после каждого вызова.
- Формирующие механизмы для международного текста неоднократно обновлялись для Windows/Uniscribe и для Avalon (Windows Presentation Foundation), но не были обновлены для GDI +, что заставляет международную поддержку поддержки новых языков не иметь одинакового уровня качество.
Таким образом, они знали, что хотят изменить платформу .NET, чтобы прекратить использование системы визуализации GDI + и использовать GDI. Сначала они надеялись, что они могут просто измениться:
graphics.DrawString
для вызова старого API DrawText
вместо GDI+. Но они не могли сделать текстовое обертывание и интервал точно так же, как и GDI +.
В Windows Forms 2.0 мы добавили поддержку рисования текста GDI. Сначала у нас были грандиозные планы выталкивания и подталкивания в API DrawText, чтобы мы могли точно определить, как работает API GDI + DrawString. На самом деле я думаю, что мы довольно близки, но существуют фундаментальные различия в переносе слов и интервалах между символами, которые, как простые потребители обоих API, Windows Forms не могут решить.
Итак, теперь мы сталкиваемся с проблемой: мы хотим переключить всех на новые API TextRenderer, чтобы текст выглядел лучше, лучше локализовать, более последовательно использовать другие диалоги в операционной системе...... но мы не хотим разорвать людей, рассчитывающих на строку GDI + measure для расчета того, где их текст должен выстраиваться в линию.
Поэтому они были вынуждены оставить graphics.DrawString
для вызова GDI + (соображения совместимости; люди, которые звонили graphics.DrawString
, внезапно обнаруживали, что их текст не обертывал способ, которым он использовался). Из MSDN:
Класс TextRenderer GDI был представлен в .NET Framework 2.0 для повышения производительности, улучшения текста и улучшения поддержки международные шрифты. В более ранних версиях .NET Framework для выполнения всего текстового рендеринга использовался класс Graphics на основе GDI+. GDI вычисляет интервал между символами и перенос слов иначе, чем GDI+. В приложении Windows Forms, использующем класс Graphics для визуализации текста, это может вызвать текст для элементов управления, которые используют TextRenderer, чтобы отличаться от другого текста приложения. Чтобы устранить эту несовместимость, вы можете установить для свойства
UseCompatibleTextRendering
значение true для определенного элемента управления. Чтобы установитьUseCompatibleTextRendering
в true для всех поддерживаемых элементов управления в приложении, вызовите метод Application.SetCompatibleTextRenderingDefault с параметром true.
Создан новый статический класс TextRenderer
для переноса текста GDI. Он имеет два метода:
TextRenderer.MeasureText
TextRenderer.DrawText
Примечание.
TextRenderer
является оберткой вокруг GDI, аgraphics.DrawString
по-прежнему является оберткой вокруг GDI +.
Затем возникла проблема с тем, что делать со всеми существующими элементами управления .NET, например:
-
Label
-
Button
-
TextBox
Они хотели переключить их на использование TextRenderer
(т.е. GDI), но они должны были быть осторожны. Могут быть люди, которые зависели от их элементов управления, как это было в .NET 1.1. И так родился "совместимый текстовый рендеринг".
По умолчанию элементы управления в приложении ведут себя так же, как в .NET 1.1 (они "совместимы" ).
Режим отключите совместимость, вызвав:
Application.SetCompatibleTextRenderingDefault(false);
Это делает ваше приложение лучше, быстрее, с лучшей международной поддержкой. Подводя итог:
SetCompatibleTextRenderingDefault(true) SetCompatibleTextRenderingDefault(false)
======================================= ========================================
default opt-in
bad good
the one we don't want to use the one we want to use
uses GDI+ for text rendering uses GDI for text rendering
graphics.MeasureString TextRenderer.MeasureText
graphics.DrawString TextRenderer.DrawText
Behaves same as 1.1 Behaves *similar* to 1.1
Looks better
Localizes better
Faster
Также полезно отметить отображение между GDI + TextRenderingHint
и соответствующим LOGFONT
Качество, используемое для рисования шрифта GDI:
TextRenderingHint mapped by TextRenderer to LOGFONT quality
======================== =========================================================
ClearTypeGridFit CLEARTYPE_QUALITY (5) (Windows XP: CLEARTYPE_NATURAL (6))
AntiAliasGridFit ANTIALIASED_QUALITY (4)
AntiAlias ANTIALIASED_QUALITY (4)
SingleBitPerPixelGridFit PROOF_QUALITY (2)
SingleBitPerPixel DRAFT_QUALITY (1)
else (e.g.SystemDefault) DEFAULT_QUALITY (0)
Примеры
Здесь некоторые сравнения GDI + (graphics.DrawString) стихи GDI (TextRenderer.DrawText):
GDI +: TextRenderingHintClearTypeGridFit
, GDI: CLEARTYPE_QUALITY
:
GDI +: TextRenderingHintAntiAlias
, GDI: ANTIALIASED_QUALITY
:
GDI +: TextRenderingHintAntiAliasGridFit
, GDI: не поддерживается, использует ANTIALIASED_QUALITY:
GDI +: TextRenderingHintSingleBitPerPixelGridFit
, GDI: PROOF_QUALITY
:
GDI +: TextRenderingHintSingleBitPerPixel
, GDI: DRAFT_QUALITY
:
Я считаю нечетным, что DRAFT_QUALITY
идентичен PROOF_QUALITY
, который идентичен CLEARTYPE_QUALITY
.
См. также
- UseCompatibleTextRendering - совместим с whaaaaaat?
- Сортировка всего: Быстрый просмотр Whidbey TextRenderer
- MSDN: структура LOGFONT
- AppCompat Guy: GDI и GDI + Эффективность рендеринга текста
- GDI + текст, независимость разрешения и методы рендеринга. Или - Почему мой текст выглядит по-разному в GDI + и в GDI?
Ответ 3
Мой личный опыт (я знаю только эти два различия):
DrawString поддерживает Alpha Channel, Anti Aliasing
TextRenderer поддерживает Uniscribe
Ответ 4
Я просто поставлю тестовый код:
class Form1: Form
{
private string str = "hello world hello world hello world";
private int x = 32, yLabel = 0, yDraw = 64, yRenderer = 32;
public Form1()
{
Font = new Font("Times", 16);
Label label = new Label();
label.BorderStyle = BorderStyle.FixedSingle;
label.AutoSize = true;
label.Text = str;
label.Location = new Point(x, yLabel);
Controls.Add(label);
}
protected override void OnPaint(PaintEventArgs e)
{
SizeF a;
// TextRenderer
a = TextRenderer.MeasureText(str, Font);
TextRenderer.DrawText(e.Graphics, str, Font, new Point(x, yRenderer), Color.Pink);
e.Graphics.DrawRectangle(new Pen(Color.Blue), x, yRenderer, a.Width, a.Height);
// DrawString
e.Graphics.DrawString(str, Font, new SolidBrush(Color.Red), x, yDraw);
a = e.Graphics.MeasureString(str, Font);
e.Graphics.DrawRectangle(new Pen(Color.Lime), x, yDraw, a.Width, a.Height);
base.OnPaint(e);
}
}
Нижняя строка: по сравнению с простой меткой, TextRenderer является более точным.