Click here to Skip to main content
15,886,067 members
Articles / Programming Languages / Visual Basic
Article

Overlay Text To Fit on Any Image

Rate me:
Please Sign up or sign in to vote.
4.60/5 (18 votes)
11 Aug 2004CPOL3 min read 187.4K   5K   58   27
Use of MeasureString and DrawString to produce text overlays on any image.

Image 1

Introduction

Image manipulation in .NET is far simpler than it has been in the past - even VB users get to play with GDI+! This sample shows how to draw semi-transparent text onto an image so that it fills (at least most of) the image area.

New in v.1.2: the core overlay function has been ported to C#. When you run the code in the demo, it will alternate between using the original VB and the C# implementation (for lack of anything better to do).

Background

This sample is built around actual production code that I use to draw the program environment (e.g. Development, QA, etc.) onto the application's splash screen. It could also be used to "rubber stamp" an image, or whatever else you can dream up.

Using the code

The main code is in the function (VB):

VB
Public Function Overlay(ByVal img As Image, ByVal OverlayText As String, _
  ByVal OverlayFont As Font, ByVal OverlayColor As Color, ByVal AddAlpha As Boolean, _
  ByVal AddShadow As Boolean, ByVal Position As Drawing.ContentAlignment, _
  ByVal PercentFill As Single) As Bitmap

OR (C#):

C#
public static Bitmap TextOverlay( Image img,  
  string  OverlayText,  Font OverlayFont,  
  Color OverlayColor,  bool AddAlpha,  bool AddShadow,  
  System.Drawing.ContentAlignment Position,  float PercentFill) 
Where:
  • img is any loaded image reference,
  • OverlayText is the text to draw onto the image,
  • OverlayFont is the font to use (size will be calculated),
  • OverlayColor is the color to use,
  • AddAlpha enables transparency (amount is calculated),
  • AddShadow adds a drop shadow
  • Position sets the text position on the image
  • PercentFill sets the relative fill factor (0-100%)

The function returns a bitmap. The text will wrap (if necessary) and will fill approximately PercentFill of the image's area. When using transparency (alpha), the shorter the text, the greater the transparency.

Points of Interest

Pretty much all the work in the function is simply to determine the correct font size to use. This is done in several steps:

  1. Determine the area required to draw the text as a single line, using initial font size:
    The Code Project: Your Visual Studio .NET Homepage
  2. Estimate a scaling factor by comparing the text area to the image area * PercentFill (default = 80%):
    Scaling Factor = Square Root(80% Image Area / Text Area)
    = Square Root(51725 px2/ 3998 px2) = 3.6
  3. Scale the font by that factor, then measure the text to fit 90% (SQRT(80%)) of the image width, but allow the height to run over. This is necessary because MeasureString will leave off lines if there isn't enough room, and will return only the size used and not the size needed.
    The Code Project:
    Your Visual
    Studio .NET
    Homepage
    <-- Layout too tall for image
  4. Reduce the font size (if necessary) and remeasure until the width and height are within limits.
  5. Once the appropriate size is found, position the layout rectangle on the image and draw:
    The Code Project: Your Visual
    Studio .NET Homepage
    <-- Final layout

At first I was concerned about (in)efficiency, since the function must make an initial guess at the font size, then test to see how well it fits, and adjust until the text will actually fit on the given image. This is because you must measure the string with a specific font size, but the actual area required depends on how well (or not) the text can "flow" into the region -- wrapping to multiple lines when necessary. However, changing the font size often changes how the text wraps, thereby changing the overall area required to print it. In testing, however, I found that the "reduction loop" only rarely took two passes to fit the text, and often the initial estimate did not require adjusting -- especially for long, frequently breaking text (like a sentence). For those who like numbers, various stats are written to the Console when run from the IDE.

Areas of Improvement

  • It would be more interesting to draw the text at an angle (diagonally). Still looking for someone to tackle those calculations!

History

Changes in 1.1
  • Added Positioning and %Fill as suggested by Mike.
  • Added Text Rendering Hint as suggested by Thomas.

Changes in 1.2

  • Added Save As for cliven
  • Added Load from for Bariah
  • Added StringFormat.GenericTypographic to
    MeasureString( ) 
    for more accurate measurements
  • Moved core function to separate assembly (for easy inclusion in your own solution), AAANNNDDDD
  • Ported core function to C# for all you "purists" out there.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralCan't see text on the image Pin
bcodebox16-Mar-10 5:46
bcodebox16-Mar-10 5:46 
GeneralRe: Can't see text on the image Pin
GWSyZyGy18-Mar-10 4:37
GWSyZyGy18-Mar-10 4:37 
GeneralProblem with TIF image Pin
Member 340544815-Feb-10 1:46
Member 340544815-Feb-10 1:46 
GeneralOverlay a smaller image on a larger image Pin
arsal_shaikh4-Sep-08 19:23
arsal_shaikh4-Sep-08 19:23 
GeneralRe: Overlay a smaller image on a larger image Pin
GWSyZyGy5-Sep-08 6:06
GWSyZyGy5-Sep-08 6:06 
GeneralCarriage Returns Pin
MrTeQ23-Aug-07 4:27
MrTeQ23-Aug-07 4:27 
GeneralRe: Carriage Returns Pin
GWSyZyGy5-Sep-08 6:01
GWSyZyGy5-Sep-08 6:01 
GeneralAnnotation. Pin
Rajesh Dabhi4-Jun-06 18:57
Rajesh Dabhi4-Jun-06 18:57 
GeneralRe: Annotation. Pin
GWSyZyGy12-Jun-06 5:57
GWSyZyGy12-Jun-06 5:57 
GeneralOverlay outside the main Window Pin
ffortier2-Dec-05 18:10
ffortier2-Dec-05 18:10 
NewsRe: Overlay outside the main Window Pin
GWSyZyGy5-Dec-05 11:47
GWSyZyGy5-Dec-05 11:47 
GeneralThanks so much... Pin
Paul Selormey28-Jan-05 23:44
Paul Selormey28-Jan-05 23:44 
GeneralRe: Thanks so much... Pin
GWSyZyGy31-Jan-05 5:22
GWSyZyGy31-Jan-05 5:22 
GeneralRe: Thanks so much... Pin
Paul Selormey31-Jan-05 5:52
Paul Selormey31-Jan-05 5:52 
GeneralRe: Thanks so much... Pin
Tim McCurdy19-Sep-05 5:58
Tim McCurdy19-Sep-05 5:58 
Generalnice article! Pin
vpas6-Jan-05 17:57
vpas6-Jan-05 17:57 
GeneralNon Destructive Text Overlay Pin
davemc75916-Sep-04 14:56
davemc75916-Sep-04 14:56 
GeneralRe: Non Destructive Text Overlay Pin
GWSyZyGy17-Sep-04 4:53
GWSyZyGy17-Sep-04 4:53 
Generalload image Pin
Bariah4-Aug-04 16:19
Bariah4-Aug-04 16:19 
GeneralRe: load image Pin
GWSyZyGy9-Aug-04 5:49
GWSyZyGy9-Aug-04 5:49 
GeneralThe Image is Dirty Pin
cliven14-Jun-04 23:40
cliven14-Jun-04 23:40 
GeneralRe: The Image is Dirty Pin
GWSyZyGy15-Jun-04 4:12
GWSyZyGy15-Jun-04 4:12 
GeneralRe: The Image is Dirty Pin
cliven15-Jun-04 15:36
cliven15-Jun-04 15:36 
GeneralAnti Alias Pin
Thomas_fn18-Sep-03 9:27
Thomas_fn18-Sep-03 9:27 
GeneralNext step: add positioning! Pin
nzmike23-Jul-03 12:53
nzmike23-Jul-03 12:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.