views:

240

answers:

1

When rendering text into a bitmap, I find that text looks very bad when rendered on top of an area with non-opaque alpha. The problem is progressively worse as the underlying pixels become more transparent. If I had to guess I'd say that when underlying pixels are transparent, the text renderer draws any anti-aliased 'gray' pixels as solid black.

Here are some screenshots:

Text drawn on top of transparent pixels:

alt text

Text drawn on top of semi-transparent pixels:

alt text

Text drawn on opaque pixels:

alt text

Here is the code used to render the text:

    g.SmoothingMode = SmoothingMode.HighQuality;
    g.DrawString("Press the spacebar", Font, Brushes.Black, textLeft, textTop);
+1  A: 

The first output is what you get when you draw black text on a black background, probably Color.Transparent. The 2nd was drawn on an almost-black background. The 3rd was drawn on the same background it is being displayed with.

Anti-aliasing cannot work when on a transparent background. The colors used for the anti-aliasing pixels will not blend the letter shape into the background when the text is displayed with a different background. Those pixels will now become very noticeable and make the text look very bad.

Note that SmoothingMode doesn't affect text output. It will look slightly less bad if you use a lower quality TextRenderingHint and a background color that's grayish with a alpha of zero. Only TextRenderingHint.SingleBitPerPixelGridFit avoids all anti-aliasing troubles.

Getting a perfect fix for this is very difficult. Vista's glass effect on the window title bar uses very subtle shading to give the text a well defined background color. You'd need SysInternals' ZoomIt tool to see it. Never seen anybody do this themselves.

Hans Passant
Ugh. I suppose I could draw black text onto white on a temporary bitmap, convert white to transparent, and grey to semi-transparent black, then draw this to the final bitmap. I'll try different TextRenderingHints. Otherwise, I think the effect with partial background transparency isn't too bad. One thing though - in each case, the background is the same color (off-white) with different transparency, so I wouldnt expect text to draw like this with an 'effective' background color of black.
mackenir
Not sure what you mean. Key problem is the GDI cannot see the transparency, it sees the RGB value of the transparent color. Color.Transparent is a very bad choice, its RGB value is zero. Black.
Hans Passant
What I mean is the background is painted with off-white, with an alpha component. Not sure where you got Color.Transparent from.
mackenir
@mack: is any of this helpful or shall I just delete my post?
Hans Passant
Eeasy, tiger :)
mackenir