Sometimes we need to know the width of a given string in pixels, do you know how to compute it? Before writing some long code, please notice that the .NET framework class library provides such a method. When Googling about this issue, we find the Graphics.MeasureString Method, here is how to use it:

Graphics graphics = this.CreateGraphics();
SizeF textSize = graphics.MeasureString("How long am I?", this.Font);

Nice isn’t it? Well, there is one little problem here, how is the Graphics object created? The written code is a Windows Forms code, so the this is the Form itself. You can’t create the Graphics object by simply allocating it because it has no public constructor. The Control class contains a method for creating Graphics object, so you can create it once and use it whenever you need it later on. But, what if we are not using Windows Forms? Do we have to allocate some control just for that purpose? Fortunately, there is no need for that, we can use the TextRenderer::MeasureText Method:

Size textSize = TextRenderer.MeasureText("How long am I?", font);

The MeasureText is a static method of the TextRenderer class so it looks perfect. We can use it everywhere as a generic method for measuring text length in pixels. But can you see the problem with that method comparing to the MeasureString? Look at the returned object… The width and height returned are rounded down because the Size object is built from integers, not floats. This could lead to missing character on display unless you increase the size of the rectangle being measured a bit. In general, TextRenderer is less accurate because it uses GDI and Graphics uses GDI+.

I think that this is really a minor problem, but you can always use the first method, just don’t think that it is perfect, it has its own problems… What option would you use?

Tags :

13 Responses to “Measure String Size In Pixels (C#)”


  1. PHenry

    Said on October 9, 2008 :

    The only unknown with using the non Graphics way would be how printouts are handled. The Graphics context with the printer is going to give you different string lengths. Just something to be aware of (and requires testing :>). Great information.

  2. asp.net

    Said on October 11, 2008 :

    great review, thx

  3. adrian(ro)

    Said on January 20, 2009 :

    thx

  4. Scuba_Steve

    Said on March 1, 2009 :

    I am using TextRenderer.MeasureText to force word wrap on strings too long to fit in the containing div. The problem I am running into is that for font name Arial, it returns the same width of the string whether it is 12pt or 10pt and only one pixel less for 8pt on the same input string.

  5. Scuba_Steve

    Said on March 1, 2009 :

    Please let me know if you have any ideas why.

  6. Shahar Y

    Said on March 1, 2009 :

    @ Scuba_Steve

    Try using Graphics.MeasureString Method instead,
    it is more accurate.

  7. Kluyg

    Said on April 14, 2009 :

    TextRenderer is in Assembly System.Windows.Forms (in System.Windows.Forms.dll). So… “But, what if we are not using Windows Forms?”…
    Need to create empty image, create graphics from that image (Graphics is in Assembly System.Drawing (in System.Drawing.dll)), measure string and then dispose all that shit… I think there is no better way. It’s sad.

  8. Brandon Moore

    Said on July 14, 2010 :

    I’ve been trying to use both these methods to center text on a page and neither are accurate. One calculates the size to small and the other too large. This isn’t a big deal until you have a title directly over a grid that really is perfectly centered and then it doesn’t look good.

    I have yet to find a more accurate way to measure though :/

  9. Brandon Moore

    Said on July 14, 2010 :

    Ohh! I wrote that last comment before looking at the ‘it’s own problems’ link that contained the solution :)

  10. Paul Eden

    Said on September 20, 2010 :

    @ Kluyg

    WOnder why no-one else is picking up on that the fact that either way is a winforms solution.. fine if you’re using winform, but definately in contradiction to the OP statments.

  11. Codec

    Said on December 6, 2010 :

    Thanks

  12. Kluyg

    Said on January 2, 2011 :

    @ Paul Eden
    You can create Graphics object without using Control.CreateGraphics() method. So, the only dependency will be System.Drawing.dll. You can create somethin like this:

    //————————————

    using System;
    using System.Drawing;

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

    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)
    {
    return _graphics.MeasureString(text, font);
    }
    }

    //————————————

    Register TextMeasurer implementation of ITextMeasurer service in the IoC container of your choice.

  13. abhinaw

    Said on April 19, 2011 :

    Great!
    Thanks for the tip.

Post a Comment