2
Bitmap bmp = new Bitmap(300, 50);
Graphics gfx = Graphics.FromImage(bmp);
gfx.DrawString("Why I have black outer pixels?", new Font("Verdana", 14),
    new SolidBrush(Color.White), 0, 0);
gfx.Dispose();
bmp.Save(Application.StartupPath + "\\test.png", ImageFormat.Png);

enter image description here

I need text to be completely white. I tried different brushes like Brushes.White and etc, but all bad. What can I do? All text pixels must be white, just opacity can change.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
Kosmo零
  • 4,001
  • 9
  • 45
  • 88

2 Answers2

4

Solved: (use the textrenderinghints in combination with drawstring)

        Bitmap bmp = new Bitmap(300, 50);
        Graphics gfx = Graphics.FromImage(bmp);

        gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        gfx.DrawString("Why I have black outer pixels?", new Font("Verdana", 14),
            new SolidBrush(Color.White), 0, 0);
        gfx.Dispose();
        bmp.Save(Application.StartupPath + "\\test.png", ImageFormat.Png);
John
  • 3,627
  • 1
  • 12
  • 13
  • I can't afford any blackness. This is for game translation. The game uses white text on transparent color and adds different masks to it. So I must replace it with translated text in a same way. – Kosmo零 Jan 03 '15 at 22:09
  • Hm, this is what I like more. Thank you. – Kosmo零 Jan 03 '15 at 22:12
3

This is because the background of the bitmap is a transparent black. Try to make it a transparent white before drawing:

gfx.Clear(Color.FromArgb(0, 255, 255, 255));

Apparently this does not change anything. Use TextRenderer.DrawText instead. It allows you to specify a background color:

TextRenderer.DrawText(gfx, "text", font, point, foreColor, backColor);

However it might just fill the text rectangle. I'm not sure. Or repeat what we have done above (gfx.Clear(...)) with an overload of TextRenderer.DrawText that does not have a backColor.

gfx.Clear(Color.FromArgb(1, 255, 255, 255));
TextRenderer.DrawText(gfx, "text", font, point, Color.White)

All these tricks just seem to have no effect at all. The only option left seems to be to disable anti-aliasing. This is done with SmoothingMode for non-text drawing (lines circles etc.) and TextRenderingHint for text rendering.

gfx.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; // For text
gfx.SmoothingMode = SmoothingMode.None; // For geometrical objects
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • For some weird reason nothing changes. Did you tested it? – Kosmo零 Jan 03 '15 at 21:42
  • No. Try `gfx.Clear(Color.FromArgb(1, 255, 255, 255));`. Maybe the `Color` structure is too smart and converts the fully transparent white back to transparent black. A transparency of 1 could do the trick. – Olivier Jacot-Descombes Jan 03 '15 at 21:45
  • Nothing works again... And the version with backColor simply fills everything with white, but I need white text on transparent background. – Kosmo零 Jan 03 '15 at 21:59
  • Well, then the only option which seems to be left is to swich off anti-aliasing... `Graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit`. – Olivier Jacot-Descombes Jan 03 '15 at 22:02
  • This also didn't changed anything. – Kosmo零 Jan 03 '15 at 22:04
  • 1
    Ok, I just read the `SmoothingMode` does not affect text. Use `TextRenderingHint` instead. – Olivier Jacot-Descombes Jan 03 '15 at 22:06
  • Thank you. I this might work. Actually I already coded this: ` for (int i = 0; i < bmp.Width; i++) for (int j = 0; j < bmp.Height; j++) { Color px = bmp.GetPixel(i, j); bmp.SetPixel(i, j, Color.FromArgb(px.A, Color.White)); }` – Kosmo零 Jan 03 '15 at 22:14
  • Actually weird, you telling that need to disable anti-aliasing, but `codemonkey` enabled it at all black pixels gone. – Kosmo零 Jan 03 '15 at 22:26
  • @codemonkey: Can you explain why your solution works? Anti-aliasing seems to create these black borders; however, you explicitly switch it on! – Olivier Jacot-Descombes Jan 03 '15 at 22:30