Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to define a precise font size when drawing text using GDI+?

Tags:

c#

windows

gdi+

I'm using the following code to draw text on a bitmap :

using (Font font = new Font("Arial", 10.0f, FontStyle.Bold, GraphicsUnit.Point))
{
    //draw the text
    graphics.DrawString("Some text", font, Brushes.White, rect, stringFormat);
}

It works nice. Here is rendered text :

enter image description here

I want to make text a little bigger. If I set 11 as font size, here is what i get :

enter image description here

It is too big for what I want. I tried 10.25, 10.5 and such but it gives same result as 10.

I also try to set GraphicsUnit to Pixel but it behaves the same (no possibility to set custom font size).

Here is my question :

When drawing text using GDI+ (C#), is there a possiblity to "fine tune" size of rendered text ?


EDIT : more complete code snippet (as requested) :

using (Bitmap bitmap = new Bitmap(width, height))
using (Graphics graphics = Graphics.FromImage(bitmap))     
using (Font font = new Font("Arial", 10.0f, FontStyle.Bold, GraphicsUnit.Point))
{
   graphics.SmoothingMode = SmoothingMode.AntiAlias;
   graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

   Rectangle rect = new Rectangle(0, 0, width, height);

   //method 1
   StringFormat stringFormat = new StringFormat();
   stringFormat.Alignment = StringAlignment.Center;
   stringFormat.LineAlignment = StringAlignment.Center;
   graphics.DrawString("Some text", font, Brushes.White, rect, stringFormat);

   //method 2
   TextFormatFlags flags = TextFormatFlags.HorizontalCenter |
       TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak;       
   TextRenderer.DrawText(graphics, "Some text", font, rect, Color.White, flags);

   bitmap.Save(stream, ImageFormat.Png);          
}
like image 664
tigrou Avatar asked May 31 '12 09:05

tigrou


2 Answers

I don't know C# or the .Net libraries, but, looking at this page, it seems that selecting AntiAlias for TextRenderingHint should turn off hinting and turn on antialiasing. This will give you more in-between sizes, but possibly fuzzier text.

The issue is font hinting. When the details of a font, like the stroke width or size of a serif, are on the same order as the target device's resolution, simply scaling the design units to device units can cause lopsided, uneven text, especially when there's no antialiasing of any kind.

To avoid this, most fonts have "hints" that give special-case rules for rounding off when the resolution is limited. The effect is that you see "steps" in the size.

If you want to avoid the steps, you have to turn off "hinting". This will cause the rasterizer to ignore the special rounding off rules and just scale the design units to the device units directly. This allows you to have truly linearly-scaling text. The trade-off is that the text might not look as good at small sizes. Antialiasing can improve the symmetry, but, to many people, the text may look fuzzy.

like image 149
Adrian McCarthy Avatar answered Nov 14 '22 21:11

Adrian McCarthy


Graphics.DrawString() has severe and unsolvable accuracy problems, it is only suitable for high resolution devices like printers.

Use the .NET 2.0 TextRenderer.DrawText() method instead.

like image 33
Hans Passant Avatar answered Nov 14 '22 20:11

Hans Passant