Графика.DrawString vs TextRenderer.То drawtext?Что может поставить лучшее качество
TextRenderer основан на GDI и графике.Шнурок основан на GDI+.Какая из этих функций может обеспечить лучшее качество текста при рисовании текста на изображении.
4 ответов
только мои 2 цента: я всегда использую графику.Шнурок,за исключением когда мне нужно сделать пользовательскую роспись для моих (Windows Forms) элементов управления. Например, в списке с набором OwnerDraw, если я прикрепляю обработчик событий DrawItem, который полностью рисует элементы, включая текст элемента. Или в пользовательском контроле я должен нарисовать себя.
в приложении, которое использует визуальные стили в ОС, которая поддерживает его и имеет его включен, текст, нарисованный с графикой.DrawString выглядит "выключенным" при сравнении обычный текст, нарисованный другими элементами управления. Это, по-видимому, в основном из-за различий в способе обработки "ClearType" (или нет), хотя я не уверен, и у меня нет документов для резервного копирования этого оператора. (Он вроде выглядит как текст на .Объем 1.x или при переключении FlatStyle со стандартного на системный и v. v.)
только в таких случаях (рисование текста на элементах управления Winforms) я использую TextRenderer.DrawText, чтобы сделать текст лучше смешаться с другим контроли.
Если "смешение с туземцами" не является одной из ваших проблем (что похоже, так как вы хотите рисовать на изображении), я бы пошел на графику.шнурок. Кроме того, если вы хотите печатать, вы должны, так как TextRenderer работает только на экране (а не на холсте принтера).
я кросс-пост моего ответа из-за здесь, просто чтобы информация распространилась.
существует два способа рисования текста в .NET:
- GDI+ (
graphics.MeasureString
иgraphics.DrawString
) - GDI (
TextRenderer.MeasureText
иTextRenderer.DrawText
)
в .NET 1.1 все используется GDI+ для отрисовки текста. но были некоторые проблемы:
- есть некоторые проблемы с производительностью, вызванные несколько апатридным характером GDI+, где контексты устройства будут установлены, а затем восстановлены после каждого вызова.
- механизмы формирования для международного текста были обновлены много раз для Windows/Uniscribe и для Avalon (Windows Presentation Foundation), но не были обновлены для GDI+, что приводит к международной поддержке рендеринга для новых языков, чтобы не иметь тот же уровень качества.
поэтому они знали, что хотят изменить .NET framework, чтобы прекратить использовать GDI+система рендеринга текста, и использовать GDI. Сначала они надеялись, что смогут просто измениться:--38-->
graphics.DrawString
называть старой DrawText
API вместо GDI+. Но!--69-->они не могли сделать текстовую обертку и интервал точно такими же, как GDI+!--37-->.
в Windows Forms 2.0 добавлена поддержка рисования текста GDI. На сначала у нас были грандиозные планы тыкать и подталкивать API DrawText, чтобы мы могли сделать его точно таким, как работает API DrawString GDI+. Я действительно думаю, что мы довольно близки, но есть фундаментальные различия в обертывании слов и интервале символов, которые как простые потребители обоих API, Windows Forms не могли решить.
Итак, теперь перед нами проблема: мы хотим переключить всех на новый API TextRenderer, чтобы текст выглядел лучше, локализовать лучше рисовать более последовательно с другими диалогами в операционной системе... ...но мы не хотим разбивать людей, рассчитывающих на строку измерения GDI+ для расчетов того, где их текст должен выстраиваться.
поэтому они были вынуждены держать graphics.DrawString
для вызова GDI+ (причины совместимости; люди, которые звонили graphics.DrawString
внезапно обнаружил бы, что их текст не обернулся так, как раньше). из MSDN:
основанный GDI TextRenderer класс был представлен в .NET Framework 2.0 для повышения производительности, улучшения внешнего вида текста и улучшения поддержки международных шрифтов. В более ранних версиях .NET Framework GDI + based графика класс использовался для выполнения всего рендеринга текста. GDI вычисляет интервал между символами и перенос слов по-разному от GDI+. В приложении Windows Forms, использующем графика класс для рендеринга текста, это может привести к тексту для элементы управления, которые используют TextRenderer чтобы отличаться от другого текста в приложении. Чтобы устранить эту несовместимость, вы можете установить
UseCompatibleTextRendering
свойство правда для конкретного управления. УстановитьUseCompatibleTextRendering
to правда для всех поддерживаемых элементов управления в приложении, вызов приложение.SetCompatibleTextRenderingDefault метод с параметром правда.
новый статический 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+ (графика.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?
- сортировка все это: быстрый взгляд на TextRenderer Уидби
- MSDN: LOGFONT Структура
- AppCompat Guy: GDI против GDI + производительность рендеринга текста
- GDI + текст, независимость разрешения и методы рендеринга. Или-Почему мой текст выглядит по-разному в GDI+ и в GDI?
мой личный опыт (я знаю только эти два отличия):
DrawString поддерживает Альфа-канал, сглаживание
TextRenderer поддерживает Uniscribe
Я просто добавлю тестовый код:
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 является более точным.