» » » 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…


    '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

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

        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

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

Happy coding…

Max 🙂

Leave a Reply