Glow around text

Administrator

VB.NET Forum Admin
Joined
Jun 3, 2004
Messages
1,462
Programming Experience
10+
Windows Vista places a white glow around text in the title bar and other areas, pretty nice. Anyone have any GDI+ code to share to do this? I have a medium blue splash in an application and it would be neat to use this glow effect in the "Licensed to: [Name]" part of the splash area.

Thanks!
 
Hope this helps, function that draws text with halo to a bitmap, size of bitmap is measured according to font/size/text. You may have to make some adjustments for various font sizes, for example smaller sizes have to reduce halo by reducing the pen width of halo drawpath or removing it and only use the halo fillpath. Also larger length text may need adjusting of the halo rectangle because of rounding misalignment. Anyway, this bitmap sized to fit the text should be easy to center/align to other containers such as centering it in form.
Function:
VB.NET:
Function halotext(ByVal text As String, ByVal fnt As Font, ByVal haloColor As Color, ByVal foreColor As Color) As Bitmap
    [COLOR=darkgreen]'measure text[/COLOR]
    Dim g As Graphics = Me.CreateGraphics
    Dim sz As Size = Size.Round(g.MeasureString(text, fnt, Me.ClientSize))
    Dim rct As New Rectangle(New Point(0, 0), sz)
    g.Dispose()
    [COLOR=darkgreen]'draw halo at 1/5th size, expand later to make fuzzy edges[/COLOR]
    Dim haloBmp As New Bitmap(sz.Width \ 5, sz.Height \ 5)
    g = Graphics.FromImage(haloBmp)
    g.SmoothingMode = SmoothingMode.AntiAlias
    Dim mx As New Matrix(1.0F / 5, 0, 0, 1.0F / 5, -(1.0F / 5), -(1.0F / 5))
    g.Transform = mx
    Dim pth As New GraphicsPath()
    pth.AddString(text, fnt.FontFamily, fnt.Style, fnt.Size, rct, StringFormat.GenericTypographic)
    g.DrawPath(New Pen(haloColor, 1), pth) [COLOR=darkgreen]'experiment pen width or remove this line[/COLOR]
    g.FillPath(New SolidBrush(haloColor), pth)
    g.Dispose()
    [COLOR=darkgreen]'create full bitmap[/COLOR]
    Dim Bmp As New Bitmap(rct.Width, rct.Height)
    g = Graphics.FromImage(Bmp)
    g.SmoothingMode = SmoothingMode.AntiAlias
    g.InterpolationMode = InterpolationMode.HighQualityBicubic
    rct.Offset(1, 1) [COLOR=darkgreen]'adjustment experiment[/COLOR]
    g.DrawImage(haloBmp, rct) [COLOR=darkgreen]'expand halo[/COLOR]
    g.FillPath(New SolidBrush(foreColor), pth) [COLOR=darkgreen]'draw 'real' text[/COLOR]
    g.Dispose()
    pth.Dispose()
    Return Bmp
End Function
Example center in form code:
VB.NET:
Private haloBmp As Bitmap
 
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
    [COLOR=darkgreen]'try different settings; colors, text, font/size[/COLOR]
    Dim halocolor As Color = Color.Yellow
    Dim forecolor As Color = Color.Black
    Dim text As String = "Halo text"
    Dim fnt As Font = New Font(Me.Font.FontFamily, 50, Me.Font.Style, GraphicsUnit.Pixel)
    haloBmp = halotext(text, fnt, halocolor, forecolor)
End Sub
 
Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles MyBase.Paint
    If Not haloBmp Is Nothing Then
        Dim pt As New Point((Me.ClientSize.Width - haloBmp.Width) \ 2, (Me.ClientSize.Height - haloBmp.Height) \ 2)
        e.Graphics.DrawImageUnscaled(haloBmp, pt)
    End If
End Sub
 
Private Sub Form2_Resize(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Resize
    Me.Refresh()
End Sub
 
JohnH,

I'm still tinkering with this, your revised code is not producing as nice a halo effect. I'm trying to figure out why. Try a more normal font size like 16 or 18 and you'll see.
 
I used code I found here and came up with this, seems to work better. I used the centering routine you provided, and I tweaked the code from the C# example for slightly better rendering:

VB.NET:
[FONT=Courier New][COLOR=#0000ff]Private[/COLOR] [COLOR=#0000ff]Function[/COLOR] GetHaloText([COLOR=#0000ff]ByVal[/COLOR] displayText [COLOR=#0000ff]As[/COLOR] [COLOR=#0000ff]String[/COLOR], [COLOR=#0000ff]ByVal[/COLOR] fnt [COLOR=#0000ff]As[/COLOR] Font, [COLOR=#0000ff]ByVal[/COLOR] haloColor [COLOR=#0000ff]As[/COLOR] Color, [COLOR=#0000ff]ByVal[/COLOR] textColor [COLOR=#0000ff]As[/COLOR] Color) [COLOR=#0000ff]As[/COLOR][/FONT][FONT=Courier New] Image[/FONT]
[FONT=Courier New][COLOR=#0000ff]Dim[/COLOR] bmpOut [COLOR=#0000ff]As[/COLOR] Bitmap = [COLOR=#0000ff]Nothing[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]Using[/COLOR] g [COLOR=#0000ff]As[/COLOR][/FONT][FONT=Courier New] Graphics = Graphics.FromHwnd(IntPtr.Zero)[/FONT]
[FONT=Courier New][COLOR=#0000ff]Dim[/COLOR] sz [COLOR=#0000ff]As[/COLOR][/FONT][FONT=Courier New] SizeF = g.MeasureString(displayText, fnt)[/FONT]
[FONT=Courier New][COLOR=#0000ff]Using[/COLOR] bmp [COLOR=#0000ff]As[/COLOR] [COLOR=#0000ff]New[/COLOR] Bitmap([COLOR=#0000ff]CInt[/COLOR](sz.Width), [COLOR=#0000ff]CInt[/COLOR][/FONT][FONT=Courier New](sz.Height))[/FONT]
[FONT=Courier New][COLOR=#0000ff]Using[/COLOR] gBmp [COLOR=#0000ff]As[/COLOR][/FONT][FONT=Courier New] Graphics = Graphics.FromImage(bmp)[/FONT]
[FONT=Courier New][COLOR=#0000ff]Using[/COLOR] brBack [COLOR=#0000ff]As[/COLOR] [COLOR=#0000ff]New[/COLOR][/FONT][FONT=Courier New] SolidBrush(haloColor)[/FONT]
[FONT=Courier New][COLOR=#0000ff]Using[/COLOR] brFore [COLOR=#0000ff]As[/COLOR] [COLOR=#0000ff]New[/COLOR][/FONT][FONT=Courier New] SolidBrush(textColor)[/FONT]
[FONT=Courier New][COLOR=#0000ff]With[/COLOR][/FONT][FONT=Courier New] gBmp[/FONT]
[FONT=Courier New].SmoothingMode = SmoothingMode.AntiAlias[/FONT]
[FONT=Courier New].InterpolationMode = InterpolationMode.HighQualityBicubic[/FONT]
[FONT=Courier New].TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit[/FONT]
[FONT=Courier New].DrawString(displayText, fnt, brBack, 0, 0)[/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]With[/COLOR][/FONT]
[FONT=Courier New]bmpOut = [/FONT][FONT=Courier New][COLOR=#0000ff]New[/COLOR][/FONT][FONT=Courier New] Bitmap(bmp.Width + blurAmount, bmp.Height + blurAmount)[/FONT]
[FONT=Courier New][COLOR=#0000ff]Using[/COLOR] gBmpOut [COLOR=#0000ff]As[/COLOR][/FONT][FONT=Courier New] Graphics = Graphics.FromImage(bmpOut)[/FONT]
[FONT=Courier New][COLOR=#0000ff]With[/COLOR][/FONT][FONT=Courier New] gBmpOut[/FONT]
[FONT=Courier New].SmoothingMode = SmoothingMode.AntiAlias[/FONT]
[FONT=Courier New].InterpolationMode = InterpolationMode.HighQualityBicubic[/FONT]
[FONT=Courier New].TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit[/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]With[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]For[/COLOR] x [COLOR=#0000ff]As[/COLOR] [COLOR=#0000ff]Integer[/COLOR] = 0 [COLOR=#0000ff]To[/COLOR][/FONT][FONT=Courier New] blurAmount[/FONT]
[FONT=Courier New][COLOR=#0000ff]For[/COLOR] y [COLOR=#0000ff]As[/COLOR] [COLOR=#0000ff]Integer[/COLOR] = 0 [COLOR=#0000ff]To[/COLOR][/FONT][FONT=Courier New] blurAmount[/FONT]
[FONT=Courier New]gBmpOut.DrawImageUnscaled(bmp, x, y)[/FONT]
[COLOR=#0000ff][FONT=Courier New]Next[/FONT][/COLOR]
[COLOR=#0000ff][FONT=Courier New]Next[/FONT][/COLOR]
[FONT=Courier New]gBmpOut.DrawString(displayText, fnt, brFore, blurAmount / 2, blurAmount / 2)[/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Using[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Using[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Using[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Using[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Using[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Using[/COLOR][/FONT]
[FONT=Courier New][COLOR=#0000ff]Return[/COLOR][/FONT][FONT=Courier New] bmpOut[/FONT]
[FONT=Courier New][COLOR=#0000ff]End[/COLOR] [SIZE=3][COLOR=#0000ff][SIZE=2]Function[/SIZE][/COLOR][/SIZE][/FONT][SIZE=3]
[/SIZE]
 
JohnH,

I'm still tinkering with this, your revised code is not producing as nice a halo effect. I'm trying to figure out why. Try a more normal font size like 16 or 18 and you'll see.
Change the font size to 100 and halo drawpath pen width to 3 and you got the exact same code. One thing I forgot was antialias on the halo graphics, I have added this to the code in post 6.

I am painfully aware from trying to create generic text effect functions long time ago that aligning various font overlays at various font sizes is impossible to calculate. This also behaves vastly different for different text length/layout, sometimes it can't be done with a small font size, and usually text length longer than one or two words does not work. These kind of effects have to be hardcoded specifically for the font size and text. Pretty much what I mean by the comments about needing to experiment.

The other code kind of works at font size around 20 and blur 2, but doesn't really blur the edges.

Try the Bob Powell function again with font size 20 and comment out the halo drawpath line (the one where you can choose pen width for large font "blur level"), produces a really nice halo "mist" effect I think. Especially with a good contrast background or same backcolor as foreground color.
 
I'm trying to use this to add the effect to selected text in a richtextbox using:
VB.NET:
    Private Sub HaloEffectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles HaloEffectToolStripMenuItem.Click
        Dim Img As Image = halotext(rtbDoc.SelectedText, rtbDoc.SelectionFont, Color.Yellow, rtbDoc.SelectionColor)
        My.Computer.Clipboard.SetImage(Img)
        rtbDoc.Paste()
        Me.Refresh()
    End Sub
It replaces the selected text with the image, but it looks horrible. :(
scrnSht.png
 
Back
Top