
Text Halo EffectYou might imagine that creating the effect of an electric glow or halo around text would be nothing like drawing a soft shadow but the technique is exactly the same, just in a different place. For the soft shadow effect I took advantage of the graphics interoplation mode used for bitmap drawing to create a fuzzy edge for text. When an image is enlarged, the interpolation mode decides how pixels will be combined with their neighbors and with the original. Low quality modes simply draw the pixel as a square but high quality modes such as HighQualityBilinear and HighQualityBicubic do considerable averaging and antialiasing of pixels. For the best effect I have found that the HighQualityBilinear mode is best. The technique relies on drawing the text twice. Once to a shrunken bitmap which represents the halo, this will be expanded to full size using the interpolation mode of choice, and once at full size to create the actual text. The bitmap which is used to create the halo must be of a specific size ratio to the original text. In this case I have chosen a ratio of 1:5 so the halo text must be drawn at 1 fifth size. Here's how it works:
Using this method I created the effect shown in figure 1.
Figure 1. The text halo in action. The code which produces this effect his shown in the following listings. C# private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { //Create a bitmap in a fixed ratio to the original drawing area. Bitmap bm=new Bitmap(this.ClientSize.Width/5, this.ClientSize.Height/5); //Create a GraphicsPath object. GraphicsPath pth=new GraphicsPath(); //Add the string in the chosen style. pth.AddString("Text Halo",new FontFamily("Verdana"),(int)FontStyle.Regular,100,new Point(20,20),StringFormat.GenericTypographic); //Get the graphics object for the image. Graphics g=Graphics.FromImage(bm); //Create a matrix that shrinks the drawing output by the fixed ratio. Matrix mx=new Matrix(1.0f/5,0,0,1.0f/5,-(1.0f/5),-(1.0f/5)); //Choose an appropriate smoothing mode for the halo. g.SmoothingMode=SmoothingMode.AntiAlias; //Transform the graphics object so that the same half may be used for both halo and text output. g.Transform=mx; //Using a suitable pen... Pen p=new Pen(Color.Yellow,3); //Draw around the outline of the path g.DrawPath(p,pth); //and then fill in for good measure. g.FillPath(Brushes.Yellow,pth); //We no longer need this graphics object g.Dispose(); //this just shifts the effect a little bit so that the edge isn't cut off in the demonstration e.Graphics.Transform=new Matrix(1,0,0,1,50,50); //setup the smoothing mode for path drawing e.Graphics.SmoothingMode=SmoothingMode.AntiAlias; //and the interpolation mode for the expansion of the halo bitmap e.Graphics.InterpolationMode=InterpolationMode.HighQualityBicubic; //expand the halo making the edges nice and fuzzy. e.Graphics.DrawImage(bm,ClientRectangle,0,0,bm.Width,bm.Height,GraphicsUnit.Pixel); //Redraw the original text e.Graphics.FillPath(Brushes.Black,pth); //and you're done. pth.Dispose(); }
VB Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint 'Create a bitmap in a fixed ratio to the original drawing area. Dim bm As New Bitmap(Me.ClientSize.Width / 5, Me.ClientSize.Height / 5) 'Create a GraphicsPath object. Dim pth As New GraphicsPath() 'Add the string in the chosen style. pth.AddString("Text Halo", New FontFamily("Verdana"), CInt(FontStyle.Regular), 100, New Point(20, 20), StringFormat.GenericTypographic) 'Get the graphics object for the image. Dim g As Graphics = Graphics.FromImage(bm) 'Create a matrix that shrinks the drawing output by the fixed ratio. Dim mx As New Matrix(1F / 5, 0, 0, 1F / 5, -(1F / 5), -(1F / 5)) 'Choose an appropriate smoothing mode for the halo. g.SmoothingMode = SmoothingMode.AntiAlias 'Transform the graphics object so that the same half may be used for both halo and text output. g.Transform = mx 'Using a suitable pen... Dim p As New Pen(Color.Yellow, 3) 'Draw around the outline of the path g.DrawPath(p, pth) 'and then fill in for good measure. g.FillPath(Brushes.Yellow, pth) 'We no longer need this graphics object g.Dispose() 'this just shifts the effect a little bit so that the edge isn't cut off in the demonstration e.Graphics.Transform = New Matrix(1, 0, 0, 1, 50, 50) 'setup the smoothing mode for path drawing e.Graphics.SmoothingMode = SmoothingMode.AntiAlias 'and the interpolation mode for the expansion of the halo bitmap e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic 'expand the halo making the edges nice and fuzzy. e.Graphics.DrawImage(bm, ClientRectangle, 0, 0, bm.Width, bm.Height, GraphicsUnit.Pixel) 'Redraw the original text e.Graphics.FillPath(Brushes.Black, pth) 'and you're done. pth.Dispose() End Sub 'Form1_Paint
Copyright Robert W. Powell 2004. All rights reserved.
|