A Picture Box in VB.net That Remembers It’s Path

A couple days I was working on a personal project where I needed to sort some images (maybe more on that later :-) ) But while I was working on it I want to throw some quick thumbnails up that I could easily throw up on a panel and remove after I had I was done with them. I found out that the build in PictureBox control only holds the bitmap image and not the path to the file. I could have held this information inside an array in the class that I was working on but I realized that it would be better if I could just extend the PictureBox so then all I needed to do was set the path and it would load a thumbnail of the image.

Because the smartPictureBox class inhertis from the PictureBox class all the methods and properties of the picture box become the default for our new class. Because of this we can just add the new functionality and everything else will work as it does with a PictureBox.


Public Class smartPictureBox : Inherits System.Windows.Forms.PictureBox
    Private strFilepath As String = ""

    Property path()
        Get
            Return strFilepath
        End Get
        Set(ByVal value)
            ' save the new value
            strFilepath = value

            ' load the image
            loadImage()
        End Set
    End Property

    Private Sub loadImage()
        ' check to make sure the file exists
        If (Not System.IO.File.Exists(strFilepath)) Then
            Exit Sub
        End If

        Try
            ' read in the raw file
            Dim objRaw As System.Drawing.Image = System.Drawing.Image.FromFile(strFilepath)

            ' calculate the new width and height
            Dim newWidth As Integer = Me.Width
            Dim newHeight As Integer = Me.Height

            ' calculate the aspect ratio
            Dim ratio As Double = objRaw.Width / objRaw.Height

            ' check to see if this is a landscape
            If (ratio > 1) Then
                newWidth = Me.Width
                newHeight = Me.Width / ratio
            Else
                newHeight = Me.Height
                newWidth = Me.Height / ratio
            End If

            ' create a new image with the same size as the control
            Dim objNew As System.Drawing.Image = New System.Drawing.Bitmap(newWidth, newHeight)

            ' get a handle to the drawing interface for the new image
            Dim objGraphics As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(objNew)

            ' resize the image to fit the size of the image panel
            objGraphics.DrawImage(objRaw, 0, 0, objNew.Width, objNew.Height)

            ' set the background to the new image
            Me.BackgroundImage = objNew

            ' dispose of the full sized image
            objRaw.Dispose()

        Catch ex As Exception
            ' if there was an error loading the image we just need to display the error image
            Me.BackgroundImage = Me.ErrorImage
        End Try

    End Sub

    Public Sub New()
        ' we want this to zoom it if is resized
        Me.BackgroundImageLayout = ImageLayout.Zoom
    End Sub

End Class

As a proof of concept I loaded the control into a blank form and this is the code behind it:


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SmartPictureBox1.path = "path_to_file"
    End Sub

    Private Sub SmartPictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SmartPictureBox1.Click
        MessageBox.Show(SmartPictureBox1.path)
    End Sub
End Class

One downside to this code currently is that because the thumbnail is loaded when the path is set it doesn’t scale up well when it’s resized. This wasn’t a problem with my application because all the thumbnails stayed the same size. If this is a problem you can keep the original image around and then resize the thumbnail.

Leave a Reply