我注意到不同分辨率下Graphics.MeasureString的奇怪行为。
对于默认分辨率(96x96),我测试的不同字体大小之间存在线性关系。
然而,如果我把它提升到512 x 512,线性关系就会消失,使用测量字符串时会发生一些奇怪的事情。 (见下面的4个图)
如果我将分辨率保留为图形对象的默认大小,并测量字体大小,则这是字体大小与字符串宽度之间的关系:
图形对象,默认分辨率(96):
字体大小(X轴),特定字符串的WIDTH(Y轴)
字体大小(X轴),特定字符串的高度(Y轴)
但是,如果我更改分辨率
图形对象,512分辨率:
字体大小(X轴),特定字符串的WIDTH(Y轴)
字体大小(X轴),特定字符串的高度(Y轴)
任何人都知道为什么会发生这种情况?
谢谢你。
应该注意到我使用的是.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);
}
答案 0 :(得分:1)
这个答案是猜测,但证据非常适合。
你看到的是被包裹在两行上的字符串。
我们假设以下内容:
这适合512分辨率图形的开始,一切都线性增加。
在某些时候,宽度会急剧减少一定量,同时高度增加一倍。
这意味着一个单词被移动到第2行,它将高度加倍(2行与之前的1行),并且由于该行的最后一个单词现在位于行的开头,所以该字符串的宽度变小了一些2。
从那时起,宽度再次缓慢增加,因为字符串的部分仍然在第1行线性地随着字体大小的增加而变宽。与此同时,高度线性增加,但现在是休息前的两倍,因为2线现在变得更高,而之前是1。
在某些时候,第1行的最后一个单词再次突破最大宽度,并在第2行向下移动,之前单独存在于该单词之前,此时,宽度再次急剧下降量。
如果您要继续使用图表,我预测宽度将继续其当前模式。它每次下降的确切数量与被移动的单词的宽度成比例。同时,在某些时候,第二条线需要被打破,在这种情况下,你得到3倍的高度,然后高度将以3倍的速度增加,依此类推。
答案 1 :(得分:1)
我相信这可能会因为GDI +中的提示/网格拟合算法而发生。测试中的字体大小在字形易读性方面非常小,因此,渲染引擎会尝试对每个字形应用特殊转换以使其更清晰。这些转换在很大程度上取决于目标DPI。
值得一提的是,字体大小的大幅增加将导致更“线性”的依赖。
这个article通过一些例子更详细地解释了这些机制。
与此同时,您可以尝试修改Graphics.TextRenderingHint
属性和/或尝试使用TextRenderer
代替Graphics.DrawString
,如果这样可以帮助您解决问题。