Странное поведение графики.MeasureString в разных разрешениях - PullRequest
3 голосов
/ 02 марта 2012

Я заметил странное поведение Graphics.MeasureString при разных разрешениях.

Для разрешения по умолчанию (96x96) существует линейная зависимость между различными размерами шрифтов, которые я тестировал.

Однако, если я увеличу его до 512 x 512, линейное соотношение исчезнет, ​​и при использовании строки меры произойдет нечто действительно странное. (См. 4 графика ниже)

Если я оставлю разрешение на уровне по умолчанию для графического объекта и измерим размер шрифта, вот соотношение между размером шрифта и шириной строки:

Графический объект, разрешение по умолчанию (96):

Размер шрифта (ось X), ШИРИНА конкретной строки (ось Y) Width96

Размер шрифта (ось X), высота конкретной строки (ось Y) Height96

Однако, если я изменю разрешение

Графический объект, разрешение 512:

Размер шрифта (ось X), ШИРИНА конкретной строки (ось Y) enter image description here

Размер шрифта (ось X), высота конкретной строки (ось Y) enter image description here

Кто-нибудь знает, почему это может происходить?

Спасибо.

Следует отметить, что я использую .NET 4 (полный профиль)

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

string str = "6  CN-3 Tie EomgVeo405- 2ss>era09rni IBne 20iopv Atdrsn - Ng72";
SizeF sizef = new SizeF(855, 14.000001f);
StringFormat stringFormat = new StringFormat() 
{
    Alignment = StringAlignment.Center,
    LineAlignment = StringAlignment.Near,
    Trimming = StringTrimming.None,
    FormatFlags = StringFormatFlags.NoClip,
};

Bitmap b = new Bitmap(901, 401);
//b.SetResolution(512, 512);
Graphics g = Graphics.FromImage(b);

for (float x = origFont.Size; x >= 0.5; x -= 0.1f)
{
    var data = g.MeasureString(str, new Font("Microsoft Sans Serif", x), sizef, stringFormat);
    Console.WriteLine(x + "\t" + data.Width + "\t" + data.Height);
}

Ответы [ 2 ]

1 голос
/ 02 марта 2012

Я полагаю, что это может происходить из-за алгоритмов подсказок / подбора сетки в GDI +. Размеры шрифтов в ваших тестах чрезвычайно малы с точки зрения разборчивости глифа, и поэтому механизм рендеринга пытается применить специальные преобразования к каждому глифу, чтобы сделать его более понятным. Эти преобразования сильно зависят от целевого DPI.

Стоит также отметить, что значительное увеличение размера шрифта приведет к более «линейной» зависимости.

Эта статья объясняет эти механизмы более подробно с некоторыми примерами.

Тем временем вы можете попытаться изменить свойство Graphics.TextRenderingHint и / или попробовать TextRenderer вместо Graphics.DrawString, если это поможет вам в вашей проблеме.

1 голос
/ 02 марта 2012

Этот ответ является предположением, но свидетельство подходит ему идеально.

То, что вы видите, это строка, обернутая в две строки.

Давайте предположим следующее:

  1. Ширина текста линейно пропорциональна размеру шрифта
  2. Высота текста линейно пропорциональна размеру шрифта

Это соответствует началу вашего 512-разрешение, все увеличивается линейно.

В какой-то момент ширина резко уменьшается на определенную величину, и в то же время высота удваивается.

Это означает, что слово было перемещенона строку 2, которая удвоила высоту (2 строки против 1 ранее), и строка стала на определенную величину менее широкой, поскольку последнее слово в строке теперь находится в начале строки 2.

Оттудаon, ширина снова медленно увеличивается, так как часть строки, все еще находящаяся в строке 1, линейно расширяется при увеличении размера шрифта.В то же время высота увеличивается линейно, но теперь в два раза быстрее, чем до перерыва, поскольку теперь 2 линии становятся выше по сравнению с 1. Ранее.

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

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

...