When text on an image is hard to read, you can make it more prominent by adding a halo around it -- and you don't need a sophisticated graphics package to do it. Here's a VB.NET solution to handle the task.
Editor's note: Justin James has moved from VB.NET to C# since this article was originally published on Sept. 21, 2006, but we still thought readers would find this tip useful.
A text "halo" is a slight border around a piece of text. This is sometimes called "stroking." It's a useful technique because it helps the text overlaid onto an image stand out, particularly if the image is busy. For example, text with a halo added to a map is much more visible than text without the halo.
The halo effect is easy to achieve with a quality graphics program, such as Photoshop or The GIMP, but there's no easy way to do it programmatically. Even so, it can be done. The key is to create an object that accepts a .NET Bitmap object and adds the desired text with a halo.
Basic halo conceptThe basic concept behind our halo code is to create an image with the text itself, increase the size of the working canvas by 1 pixel in all directions (because the halo is 1 pixel wide), walk through the text image looking for all pixels that belong to the text, and shade their surrounding pixels, as long as those pixels are not also part of the text. Figure A and Figure B show a couple of examples of how halos can help text stand out. Figure A
Step 1: Create the image for the text itselfIn Listing A, we use the GraphicsMapEditor object (an instance of System.Drawing.Graphics) to discover what size the text itself will be when it is drawn and generate a Bitmap object two pixels taller and wider than the text will need. Then, we draw the text on the image using the desired brush and font.
Step 2: Add the halo
Now, we loop through the text image we created, pixel by pixel. We check to see whether the pixel has any color in it at all (by checking the alpha channel). If there is color there, we know that it's either text or halo already, and we continue on to the next pixel:
If BitmapText.GetPixel(IntegerXCounter, IntegerYCounter).A > 0 Then
EndIfOn the other hand, if that pixel is empty, we need to find out if there's any text immediately next to it. If there is, we shade that text with the halo color. We "walk around" the pixel with eight variations of the code in Listing B. The ContinueFor exists because once we've shaded the pixel once, there's no reason to waste time continuing to look around it. We use the temporary variables IntegerXToCheck and IntegerYToCheck to reduce the number of calculations performed. Depending on which direction, we flip the "direction" those two variables "look at." Listing C shows the full loop.
Step 3: Put the text on the image
The hard work is finished! It's quite easy to overlay the new image onto the original:
GraphicsBitmapEditor.DrawImage(BitmapText, TextX, TextY)
From here, we have a standard .NET Bitmap object, which can be used for a wide variety of purposes. For instance, we can save this image to disk, display it to a Web client, or put it in a PictureBox. The possibilities are endless.
Putting text halos to work
To make text halos useful, we'll want to put them into a class by themselves. The accompanying download contains a fully completed class that will generate text halos for you if you provide the text, an original image, the text and halo colors, and a font for the text. It also has a full application to use the text halos and add them to images.
The application contains and installs full source code for itself (the .NET Framework 2.0 SDK is required to compile it, and Visual Studio 2005 is recommended to best work with the source code), so that you can experiment and alter the code as you see fit. The application also makes use of basic Windows dialog components and uses the BackgroundWorker object to allow it to process the images while not having the rest of the application hang. Finally, the application demonstrates some simple techniques for creating a bitmap entirely with VB.NET code and filling it with a single color of the user's choice (for the color tiles on the interface).
J.JaDisclosure of Justin's industry affiliations: Justin James has a working arrangement with Microsoft to write an article for MSDN Magazine. He also has a contract with Spiceworks to write product buying guides.
---------------------------------------------------------------------------------------------------------------Get weekly development tips in your inbox Keep your developer skills sharp by signing up for TechRepublic's free Web Developer newsletter, delivered each Tuesday. Automatically subscribe today!