Home » Programming » C# » How to draw a shadow for a bitmap (Drop Shadow Effect in VB.NET / ASP.NET)

How to draw a shadow for a bitmap (Drop Shadow Effect in VB.NET / ASP.NET)

posted in: ASP.NET, C#, Programming, VB.Net 0

I wrote a vb.net subroutine to draw easly a shadow for a Bitmap object; It is possible get a charming shadow in different ways…

Normal black shadow to the bottom right corner
Red shadow to the bottom right corner
Shadow to the bottom left corner
Shadow to the top left corner
Shadow to the top right corner
Shadow with Opacity: “128”
Shadow with Opacity: “128” and Softness: “8”
Shadow with Opacity: “128”, Softness: “8” and Distance: “10”
Shadow without rounded edges

Copy and paste my following vb.net code in your application. it does all the hard job…

[sourcecode language=”vb”]

‘ShadowDirection:
‘ TOP_RIGHT = 1
‘ BOTTOM_RIGHT = 2
‘ BOTTOM_LEFT = 3
‘ TOP_LEFT = 4
‘ShadowOpacity: from 0 to 255
‘ShadowSoftness: from 1 to 30
‘ShadowDistance: from 1 to 50
‘ShadowRoundedEdges: True or False

‘Note:
‘If You set "transparent" as background color, this is replaced with white color.

Public Enum ShadowDirections As Integer
TOP_RIGHT = 1
BOTTOM_RIGHT = 2
BOTTOM_LEFT = 3
TOP_LEFT = 4
End Enum

<STAThread()> _
Public Sub DropShadow(ByRef SourceImage As Drawing.Bitmap, _
ByVal ShadowColor As Drawing.Color, _
ByVal BackgroundColor As Drawing.Color, _
Optional ByVal ShadowDirection As ShadowDirections = _
ShadowDirections.BOTTOM_RIGHT, _
Optional ByVal ShadowOpacity As Integer = 190, _
Optional ByVal ShadowSoftness As Integer = 4, _
Optional ByVal ShadowDistance As Integer = 5, _
Optional ByVal ShadowRoundedEdges As Boolean = True)
Dim ImgTarget As Bitmap = Nothing
Dim ImgShadow As Bitmap = Nothing
Dim g As Graphics = Nothing
Try
If SourceImage IsNot Nothing Then
If ShadowOpacity < 0 Then
ShadowOpacity = 0
ElseIf ShadowOpacity > 255 Then
ShadowOpacity = 255
End If
If ShadowSoftness < 1 Then
ShadowSoftness = 1
ElseIf ShadowSoftness > 30 Then
ShadowSoftness = 30
End If
If ShadowDistance < 1 Then
ShadowDistance = 1
ElseIf ShadowDistance > 50 Then
ShadowDistance = 50
End If
If ShadowColor = Color.Transparent Then
ShadowColor = Color.Black
End If
If BackgroundColor = Color.Transparent Then
BackgroundColor = Color.White
End If

‘get shadow
Dim shWidth As Integer = CInt(SourceImage.Width / ShadowSoftness)
Dim shHeight As Integer = CInt(SourceImage.Height / ShadowSoftness)
ImgShadow = New Bitmap(shWidth, shHeight)
g = Graphics.FromImage(ImgShadow)
g.Clear(Color.Transparent)
g.InterpolationMode = InterpolationMode.HighQualityBicubic
g.SmoothingMode = SmoothingMode.AntiAlias
Dim sre As Integer = 0
If ShadowRoundedEdges = True Then sre = 1
g.FillRectangle(New SolidBrush(Color.FromArgb(ShadowOpacity, ShadowColor)), _
sre, sre, shWidth, shHeight)
g.Dispose()

‘draw shadow
Dim d_shWidth As Integer = SourceImage.Width + ShadowDistance
Dim d_shHeight As Integer = SourceImage.Height + ShadowDistance
ImgTarget = New Bitmap(d_shWidth, d_shHeight)
g = Graphics.FromImage(ImgTarget)
g.Clear(BackgroundColor)
g.InterpolationMode = InterpolationMode.HighQualityBicubic
g.SmoothingMode = SmoothingMode.AntiAlias
g.DrawImage(ImgShadow, New Rectangle(0, 0, d_shWidth, d_shHeight), _
0, 0, ImgShadow.Width, ImgShadow.Height, GraphicsUnit.Pixel)
Select Case ShadowDirection
Case ShadowDirections.BOTTOM_RIGHT
g.DrawImage(SourceImage, _
New Rectangle(0, 0, SourceImage.Width,SourceImage.Height), _
0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel)
Case ShadowDirections.BOTTOM_LEFT
g.Dispose()
ImgTarget.RotateFlip(RotateFlipType.RotateNoneFlipX)
g = Graphics.FromImage(ImgTarget)
g.DrawImage(SourceImage, _
New Rectangle(ShadowDistance, 0, SourceImage.Width, SourceImage.Height), _
0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel)
Case ShadowDirections.TOP_LEFT
g.Dispose()
ImgTarget.RotateFlip(RotateFlipType.Rotate180FlipNone)
g = Graphics.FromImage(ImgTarget)
g.DrawImage(SourceImage, _
New Rectangle(ShadowDistance, ShadowDistance, _
SourceImage.Width, SourceImage.Height), _
0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel)
Case ShadowDirections.TOP_RIGHT
g.Dispose()
ImgTarget.RotateFlip(RotateFlipType.RotateNoneFlipY)
g = Graphics.FromImage(ImgTarget)
g.DrawImage(SourceImage, _
New Rectangle(0, ShadowDistance, SourceImage.Width, SourceImage.Height), _
0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel)
End Select

g.Dispose()
g = Nothing
ImgShadow.Dispose()
ImgShadow = Nothing

SourceImage = New Bitmap(ImgTarget)
ImgTarget.Dispose()
ImgTarget = Nothing
End If

Catch ex As Exception
If g IsNot Nothing Then
g.Dispose()
g = Nothing
End If
If ImgShadow IsNot Nothing Then
ImgShadow.Dispose()
ImgShadow = Nothing
End If
If ImgTarget IsNot Nothing Then
ImgTarget.Dispose()
ImgTarget = Nothing
End If
End Try

End Sub
[/sourcecode]

Besides, You can use this sub as in the following example (take a look at the comments…) :

[sourcecode language=”vb”] Dim file_input As String = "c:myfile.jpg"
Dim file_output As String = "c:myfilewithshadow.jpg"

‘get bitmap…
Dim sourceImage As System.Drawing.Image = System.Drawing.Image.FromFile(file_input)
Dim format As System.Drawing.Imaging.ImageFormat = sourceImage.RawFormat
Dim bmpOut As System.Drawing.Bitmap = New Bitmap(sourceImage)

‘release any reference to the original file…
While sourceImage IsNot Nothing
sourceImage.Dispose()
sourceImage = Nothing
End While

‘drop black shadow on new bitmap with white background…
DropShadow(bmpOut, Color.Black, Color.White)

‘save file…
If bmpOut IsNot Nothing Then
bmpOut.Save(file_output, format)
bmpOut.Dispose()
bmpOut = Nothing
End If
[/sourcecode]

PS:
The subroutine executes only in “STAThread” so it’s thread-safe drawing.

Happy coding…

Max 🙂

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.