TextRenderer.DrawText in Bitmap vs OnPaintBackground

前端 未结 6 991
无人共我
无人共我 2020-12-18 03:01

If I use TextRenderer.DrawText() using the Graphics object provided in the OnPaintBackground my text looks perfect. If I create my own

6条回答
  •  星月不相逢
    2020-12-18 04:03

    I believe the problem is that the clear type text rendering doesn't work if the background is transparent. A few possible solutions.

    Option 1. Fill the background of your bitmap with a color.

    If you do this (as Tim Robinson did above in his code example by using g.Clear(Color.Red)) clear type will do the right thing. But your bitmap won't be completely transparent which might not be acceptable. If you use Graphics.MeasureText, you can fill just the rectangle around your text, if you like.

    Option 2. Set TextRenderingHint = TextRenderingHintAntiAliasGridFit

    This appears to turn off clear type. The text will be rendered at a lower quality than clear type on a background, but much better than the mess clear type on no background creates.

    Option 3. Fill the text rectangle with white, draw the text and then find all the non-text pixels and put them back to transparent.

    using (Bitmap bmp = new Bitmap(someWidth, someHeight))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            // figure out where our text will go
            Point textPoint = new Point(someX, someY);
            Size textSize = g.MeasureString(someText, someFont).ToSize();
            Rectangle textRect = new Rectangle(textPoint, textSize);
    
            // fill that rect with white
            g.FillRectangle(Brushes.White, textRect);
    
            // draw the text
            g.DrawString(someText, someFont, Brushes.Black, textPoint);
    
            // set any pure white pixels back to transparent
            for (int x = textRect.Left; x <= textRect.Left + textRect.Width; x++)
            {
                for (int y = textRect.Top; y <= textRect.Top + textRect.Height; y++)
                {
                    Color c = bmp.GetPixel(x, y);
                    if (c.A == 255 && c.R == 255 && c.G == 255 && c.B == 255)
                    {
                        bmp.SetPixel(x, y, Color.Transparent);
                    }
                }
            }
        }
    }
    

    I know, it's a horrible hack, but it appears to work.

提交回复
热议问题