如何测量给定字体/大小的数字的像素宽度 (C#)
我正在尝试计算 Excel 列的像素宽度,如 这篇文章,使用 OpenXML 规范中的官方公式。但是,为了应用这个公式,我需要知道 Normal 字体的 最大数字宽度,即最宽数字的像素宽度。 OpenXML 规范给出了这个例子作为说明:
以 Calibri 字体为例,11 点字体的最大数字宽度 大小为 7 像素(96 dpi)。
我通过目视检查 Calibri 11 点数字来检查这是否正确,它确实是 7 像素宽。因此,我正在尝试创建一种方法,该方法将返回任何字体/大小的最大数字宽度。
我已遵循此问题中提出的建议,但它不会产生我期望的结果。
这是我的测试代码:
var font = new Font("Calibri", 11.0f, FontStyle.Regular);
for (var i = 0; i < 10; i++)
{
Debug.WriteLine(TextRenderer.MeasureText(i.ToString(), font));
}
这报告所有数字的宽度为 15。
请问有什么建议吗?
谢谢, 蒂姆
I am trying to calculate the pixel width of Excel columns, as described in this post, using the official formula from the OpenXML specification. However, in order to apply this formula, I need to know the Maximum Digit Width of the Normal font, which is the pixel width of the widest numeric digit. The OpenXML specification gives this example as a clarification:
Using the Calibri font as an example, the maximum digit width of 11 point font
size is 7 pixels (at 96 dpi).
I have checked that this is correct by visually examining a Calibri 11-point digit and it is indeed 7 pixels wide. So, I am trying to create a method that will return the maximum digit width for any font / size.
I have followed the recommendations made in this question, but it doesn't produce the results I am expecting.
Here's my test code:
var font = new Font("Calibri", 11.0f, FontStyle.Regular);
for (var i = 0; i < 10; i++)
{
Debug.WriteLine(TextRenderer.MeasureText(i.ToString(), font));
}
This reports that all digits have a width of 15.
Any suggestions please?
Thanks,
Tim
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先我要说的是,我将要展示的代码看起来像是一个可怕的黑客攻击,我不会将其作为解决方案来呈现。相反,我希望它能更多地揭示 MeasureText 的行为,这可能会引导您找到最终的解决方案。
我对你的代码做了一些轻微的修改。我正在测量两个下划线字符的长度。然后,在 for 循环体中,我测量两侧带有下划线的所需字符,并单独减去两个下划线字符的长度。对于测试场景,我得到的结果为 7。这样做的主要目的是确定 MeasureText 是逐个字符地填充还是在字符串的开头/结尾处填充。看来是后者了。也许这与您收到的其他一些输入相结合,将引导您找到更优雅的解决方案。
First let me say that the code I'm about to show looks like a horrible hack and I'm not presenting it as a solution. Rather, I'm hoping it reveals a little more about the behavior of MeasureText that might lead you to your final solution.
I made a slight alteration to your code. I'm measuring the length of two underscore characters. Then, in the body of the for loop I'm measuring the desired character with underscores on either side and subtracting the length of the two underscore characters alone. For the test scenario I am getting a result of 7. The main purpose of this was to determine whether MeasureText is accounting for padding on a character-by-character basis or padding at the beginning/ending of the string. It seems that it is the latter. Perhaps this, combined with some of the other input you've received, will lead you to a more elegant solution.
TextRenderer 并不总是如您所期望的那样准确:
来自 MSDN: http:// msdn.microsoft.com/en-us/library/8wafk2kt.aspx
您有
Graphics
对象还是 Control 对象吗?如果您使用这些,您可以按照您期望的方式获得准确的结果。查看 http://msdn.microsoft.com /en-us/library/6xe5hazb(VS.80).aspx
TextRenderer is not always accurate the way you would expect:
From MSDN: http://msdn.microsoft.com/en-us/library/8wafk2kt.aspx
Do you have a
Graphics
object or a Control object? If you are using these you can get accurate restults the way you would expect.Take a look at http://msdn.microsoft.com/en-us/library/6xe5hazb(VS.80).aspx
MeasureText 添加填充,尽管它大致随字体大小线性缩放,但其数量相当不可预测。诀窍是减去两个测量值以消除填充。这段代码生成了非常令人满意的数字:
输出:
这为您提供了您正在寻找的 7 个像素。请注意,您必须适应 TrueType 提示,它可以调整数字的形状,使其主干落在像素边界上。添加至少一个像素。
MeasureText adds padding, the amount is fairly unpredictable although it roughly scales linearly with the font size. The trick is to subtract two measurements to get rid of the padding. This code generated very happy numbers:
Output:
That gets you the 7 pixels you're looking for. Beware that you'll have to accommodate TrueType hinting, it can adjust the shape of the digit so that its main stems fall on pixel boundaries. Add at least one pixel.
测量文本宽度可能是一场噩梦。我不知道为什么他们让它如此令人困惑。
这是我测量文本长度的最准确方法:
Measuring text widths can be a nighmare.. I dont know why they made it so confusing..
Heres the most accurate way Ive got to measure the length of text :
我不能 100% 确定这就是您真正需要的。
但您可能想看看这个 Microsoft 页面:
I am not 100% sure it is what you exactly need.
But you may want to have a look at this Microsoft page: