Click here to Skip to main content
Click here to Skip to main content

Overlay Text To Fit on Any Image

, 11 Aug 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
Use of MeasureString and DrawString to produce text overlays on any image.

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):

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#):

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)

Share

About the Author

GWSyZyGy
Team Leader
United States United States
No Biography provided

Comments and Discussions

 
GeneralCan't see text on the image Pinmemberbcodebox16-Mar-10 6:46 
GeneralRe: Can't see text on the image PinmemberGWSyZyGy18-Mar-10 5:37 
GeneralProblem with TIF image PinmemberMember 340544815-Feb-10 2:46 
GeneralOverlay a smaller image on a larger image Pinmemberarsal_shaikh4-Sep-08 20:23 
GeneralRe: Overlay a smaller image on a larger image PinmemberGWSyZyGy5-Sep-08 7:06 
GeneralCarriage Returns PinmemberMrTeQ23-Aug-07 5:27 
GeneralRe: Carriage Returns PinmemberGWSyZyGy5-Sep-08 7:01 
GeneralAnnotation. PinmemberRajesh Dabhi4-Jun-06 19:57 
GeneralRe: Annotation. PinmemberGWSyZyGy12-Jun-06 6:57 
GeneralOverlay outside the main Window Pinmemberffortier2-Dec-05 19:10 
NewsRe: Overlay outside the main Window PinmemberGWSyZyGy5-Dec-05 12:47 
GeneralThanks so much... PinmemberPaul Selormey29-Jan-05 0:44 
GeneralRe: Thanks so much... PinsussGWSyZyGy31-Jan-05 6:22 
GeneralRe: Thanks so much... PinmemberPaul Selormey31-Jan-05 6:52 
GeneralRe: Thanks so much... PinmemberTim McCurdy19-Sep-05 6:58 
Generalnice article! Pinmembervpas6-Jan-05 18:57 
GeneralNon Destructive Text Overlay Pinsussdavemc75916-Sep-04 15:56 
GeneralRe: Non Destructive Text Overlay PinsussGWSyZyGy17-Sep-04 5:53 
Generalload image PinsussBariah4-Aug-04 17:19 
GeneralRe: load image PinsussGWSyZyGy9-Aug-04 6:49 
GeneralThe Image is Dirty Pinmembercliven15-Jun-04 0:40 
GeneralRe: The Image is Dirty PinsussGWSyZyGy15-Jun-04 5:12 
GeneralRe: The Image is Dirty Pinmembercliven15-Jun-04 16:36 
GeneralAnti Alias Pinmemberfanell18-Sep-03 10:27 
GeneralNext step: add positioning! Pinmembernzmike23-Jul-03 13:53 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150302.1 | Last Updated 12 Aug 2004
Article Copyright 2003 by GWSyZyGy
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid