TextRenderer.MeasureText和Graphics.MeasureString的大小不匹配

时间:2011-07-15 09:13:45

标签: c# gdi+

这不是一个四舍五入的问题。差异〜5+像素。

测试用例字符串:“”MACD(26,12,9)-0.000016“

e.Graphics.MeasureString("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width)
TextRenderer.MeasureText("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width)

结果总是:

139.3942
134

为什么尺寸差异如此之大?我只需要在外面绘制圆形宽度的方法。但它应该与MeasureString匹配,反之亦然。

2 个答案:

答案 0 :(得分:58)

TextRenderer使用GDI呈现文本,而Graphics使用GDI +。两者使用略有不同的方法来布局文本,因此大小不同。

您应该使用哪一个取决于最终用于实际绘制文本的内容。如果您使用GDI + Graphics.DrawString进行绘制,请使用Graphics.MeasureString进行衡量。如果您使用GDI TextRenderer.DrawText绘图,请使用TextRenderer.MeasureText进行衡量。

如果文本将显示在Windows窗体控件中,如果TextRenderer设置为UseCompatibleTextRendering(这是默认设置),则会使用false

在您的问题的各行之间进行阅读,您似乎正在使用TextRenderer,因为您在Graphics事件之外没有Paint个实例。如果是这种情况,您可以自己创建一个来进行测量:

using( Graphics g = someControl.CreateGraphics() )
{
    SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont);
}

如果您无权访问控件来创建图形实例,您可以使用它来为屏幕创建一个控件,这可以很好地用于测量目的。

using( Graphics g = Graphics.FromHwnd(IntPtr.Zero) )
{
     SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont);
}

答案 1 :(得分:1)

我使用以下类在paint事件之外使用MeasureString,它运行得很好。

public interface ITextMeasurer
    {
        SizeF MeasureString(string text, Font font, StringFormat format);
    }

    public class TextMeasurer : ITextMeasurer
    {
        private readonly Image _fakeImage;
        private readonly Graphics _graphics;

        public TextMeasurer()
        {
            _fakeImage = new Bitmap(1, 1);
            _graphics = Graphics.FromImage(_fakeImage);
        }

        public SizeF MeasureString(string text, Font font, StringFormat format)
        {
            return _graphics.MeasureString(text, font, int.MaxValue, format);
        }
    }