How to drawString with text space of pixel?

mc 7,296 Reputation points
2026-05-18T01:12:44.1533333+00:00

I am using winform .net 10 (or 9)

how to use the Grahpics to Draw a text with pixels space?

for example I am drawing :welcome and then I will scale the bitmap to max and the check the pixel among each char

User's image

above picture demonstrates there is no pixel among the char.

User's image

and this picuture . there is 3 pixels between w and l

can I set the pixel number and then I will get the bitmap that has the pixels between chars?

I know you may say NO it is not possible. and then I want to ask how to get the pixel when I set it to 1 or 2 or other numbers? when I set a number and then draw it I want to get how many pixels I will get between each chars.

thank you !!

Developer technologies | Windows Forms
0 comments No comments

Answer accepted by question author
Jack Dang (WICLOUD CORPORATION) 18,975 Reputation points Microsoft External Staff Moderator
2026-05-18T06:03:12.11+00:00

Hi @mc ,

Thanks for reaching out.

The code snippets below are intended as reference samples, so you may need to adjust them a little to match your own project structure, rendering settings, and font handling.

Graphics.DrawString() does not have a built-in option to set character spacing in exact pixel units. It uses the font's own metrics, so if you draw the whole word in one call, you cannot tell it to always leave exactly 1, 2, or 3 visible pixels between letters.

If you just want to add spacing, the usual way is to draw one character at a time and move the x position forward yourself. Here is a simple sample:

private static Bitmap DrawTextWithSpacing(string text, Font font, int extraPixels)
{
  using var measureBmp = new Bitmap(1, 1);
  using var measureG = Graphics.FromImage(measureBmp);
  using var format = (StringFormat)StringFormat.GenericTypographic.Clone();

  format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
  measureG.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;

  float width = 0;
  float height = font.GetHeight(measureG);

  foreach (char c in text)
  {
    SizeF size = measureG.MeasureString(c.ToString(), font, int.MaxValue, format);
    width += size.Width + extraPixels;
  }

  if (text.Length > 0)
    width -= extraPixels;

  var bmp = new Bitmap((int)Math.Ceiling(width), (int)Math.Ceiling(height));

  using Graphics g = Graphics.FromImage(bmp);
  using var brush = new SolidBrush(Color.Black);

  g.Clear(Color.White);
  g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;

  float x = 0;

  foreach (char c in text)
  {
    string s = c.ToString();
    g.DrawString(s, font, brush, x, 0, format);

    SizeF size = g.MeasureString(s, font, int.MaxValue, format);
    x += size.Width + extraPixels;
  }

  return bmp;
}

And this is how you could call it:

using Font font = new Font("Arial", 20, FontStyle.Regular, GraphicsUnit.Pixel);
Bitmap bmp = DrawTextWithSpacing("welcome", font, 3);

That said, this gives you extra drawing space, not an exact visible pixel gap. A font may already have empty pixels on the left or right side of a character, so the real gap you see in the bitmap can be larger or smaller than the value you add.

If your real goal is to know how many visible blank pixel columns you ended up with, then yes, you can get that, but you need to inspect the bitmap after rendering. A simple way is to render each character separately, find the first and last non-background pixel column for each glyph, and then calculate the gap from those bounds.

This helper shows the basic idea for finding the visible bounds:

private static Rectangle GetInkBounds(Bitmap bmp, Color background)
{
  int left = bmp.Width;
  int top = bmp.Height;
  int right = -1;
  int bottom = -1;

  for (int y = 0; y < bmp.Height; y++)
  {
    for (int x = 0; x < bmp.Width; x++)
    {
      if (bmp.GetPixel(x, y).ToArgb() != background.ToArgb())
      {
        if (x < left) left = x;
        if (y < top) top = y;
        if (x > right) right = x;
        if (y > bottom) bottom = y;
      }
    }
  }

  if (right < left || bottom < top)
    return Rectangle.Empty;

  return Rectangle.FromLTRB(left, top, right + 1, bottom + 1);
}

Hope this helps! If my explanation and the information I provided were helpful, I would greatly appreciate it if you could follow the instructions here so others with the same problem can benefit as well.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

1 additional answer

Sort by: Most helpful
  1. AI answer

    2026-05-18T01:13:02.2566667+00:00

    GDI+ Graphics.DrawString does not expose a property to directly set “N pixels between characters”. Character spacing is controlled by the font and layout engine. To control spacing or to measure the actual gaps, draw each character separately and use Graphics.MeasureString (or MeasureCharacterRanges) to compute positions.

    A simple approach:

    1. Choose a font created in pixel units so that measurements map directly to pixels:
         var font = new Font("Arial", 16, FontStyle.Regular, GraphicsUnit.Pixel);
      
    2. Measure each character’s width:
         float[] charWidths = new float[text.Length];
         for (int i = 0; i < text.Length; i++)
         {
             string ch = text[i].ToString();
             SizeF size = g.MeasureString(ch, font); // g is Graphics
             charWidths[i] = size.Width;            // width in pixels (PageUnit)
         }
      
    3. Draw characters manually with a fixed pixel gap, for example 3 pixels:
         float gap = 3f;              // desired pixels between characters
         float x = startX;            // starting X position
         float y = startY;            // baseline Y
         
         for (int i = 0; i < text.Length; i++)
         {
             string ch = text[i].ToString();
             g.DrawString(ch, font, Brushes.Black, new PointF(x, y));
         
             // advance by character width + desired gap
             SizeF size = g.MeasureString(ch, font);
             x += size.Width + gap;
         }
      

    This way the gap between the bounding boxes of adjacent characters is the chosen gap value in pixels (subject to the extra overhang space that MeasureString adds). If more precise layout is needed (for example, ignoring the extra side bearings), use Graphics.MeasureCharacterRanges with a StringFormat configured for typographic metrics as suggested in the MeasureString remarks.

    To find out how many pixels of empty space actually appear between two characters after drawing, measure and compare positions:

    1. Measure the first character’s width.
    2. Measure the width of the substring containing both characters.
    3. The difference between (width of both) and (sum of individual widths) approximates the spacing and overhang; by controlling the positions manually as above, the gap is known (gap).

    Key points from the platform behavior:

    • Graphics.DrawString can draw text at a specified point or within a rectangle, but not with a configurable inter-character spacing parameter.
    • Graphics.MeasureString returns the size of text in the units of Graphics.PageUnit and includes a small extra space before and after the string for overhanging glyphs.
    • For layout-quality metrics, use MeasureCharacterRanges or MeasureString overloads that take StringFormat and GenericTypographic, and set TextRenderingHint to AntiAlias.

    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.