Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Newbie  »  A Simple Photo Browser  »  Zooming
 »  Home  »  Windows Development  »  A Simple Photo Browser  »  Zooming
 »  Home  »  Windows Development  »  Win Forms  »  A Simple Photo Browser  »  Zooming
A Simple Photo Browser
by Chris Mills | Published  04/14/2006 | .NET Newbie Windows Development Win Forms | Rating:

Now we have created the basic application we will expand it to allow the user to both rotate and flip images as well as zoom in and out on the image displayed.  We'll also look at re-arranging thumbnails on the panel so they fill it after it is resized.


Currently our application only displays images at 100% size.  Modern digital cameras are capable if taking photos at resolutions several times that of the a PCs monitor.  This means that some users may only be able to see less than a quarter of their image on the screen at any time.  In order to view the complete image we need to be able to zoom in or out to resize the image to fit the screen.

We'll start by declaring the variables that will hold the current zoom factor and the amount it will be increased or decreased. Add the following declarations at class level.

    ' Sets the initial zoom factor to 100%
    Dim dZoomFactor As Double = 1
    ' Specifies that the zoom factor will be changed in increments of 15%
    Const dZoomIncrements As Double = 0.15

Currently we are using the SizeMode property of the PictureBox "picPhoto" set to "AutoSize" so that the application automatically displays the selected photo at 100% size.  For our zooming functionality we need to change the size mode of the PictureBox "picPhoto" to "StretchImage".  When a PictureBox has its SizeMode property set to "StretchImage" it automatically stretches the image to fit its current size.  To zoom in our out on out image we are going to alter the size of the PictureBox and it will stretch the image to fit.  As an example, to display an image at 200% size we would set the dimensions of the PictureBox to twice the size of the photo it contains.

Now we're going to add a function to redraw the photo after a zoom operation.  Basically this function calculates and sets the new size of the PictureBox using the zoom factor variables we declared earlier.  To make our application to be easy to use we will keep area zoomed in at the same location on the screen after the zoom operation is complete - this is where things start to get a little more complicated… 

The function I have written for this task has two arguments, the X and Y coordinates of the position on the panel that will remain in the same place on the screen after the zooming operation.  This function will allow us to add mouse wheel zooming to our application so that the user can hold the mouse over a specific location on a photo and zoom in on that location.  Add the following function to your application's code:

    Private Sub ReDrawPhoto(ByVal xPos As Integer, ByVal yPos As Integer)

        Dim dPicStaticXPos, dPicStaticYPos As Double
        Dim dPanelStaticXPos, dPanelStaticYPos As Double
        Dim iNewXPos, iNewYPos As Integer

        If Not picPhoto.Image Is Nothing Then
            ' Get the position on the picture in pixels of
            ' the cordinates specified in the function, we will use this to
            ' ensure these cordinates stay in the same position each time we redraw the photo
            dPicStaticXPos = xPos / (picPhoto.Width / picPhoto.Image.Width)
            dPicStaticYPos = yPos / (picPhoto.Height / picPhoto.Image.Height)
            dPanelStaticXPos = xPos + pnlPhoto.AutoScrollPosition.X
            dPanelStaticYPos = yPos + pnlPhoto.AutoScrollPosition.Y

            ' Set the new image height and width using the zoom factor
            picPhoto.Height = CInt(picPhoto.Image.Height * dZoomFactor)
            picPhoto.Width = CInt(picPhoto.Image.Width * dZoomFactor)

            ' Set the AutoScrollPosition so that the point clicked on is in the same position on the screen after zooming
            iNewXPos = CInt((dPicStaticXPos * dZoomFactor) - dPanelStaticXPos)
            iNewYPos = CInt((dPicStaticYPos * dZoomFactor) - dPanelStaticYPos)
            pnlPhoto.AutoScrollPosition = New Drawing.Point(iNewXPos, iNewYPos)
        End If

    End Sub

Now we'll add a function to get the image to fit the available space on the screen.  This function calculates the maximum size of the image that can fit on the screen and adjusts the zoom factor accordingly.  Add the function below to your code:

    Private Sub FitPhotoToPanel()

        ' Assumes that the Panel is approximately square
        ' Calculates the maximum zoom factor that can be used and still
        ' fit the image on the panel used to contain it
        If picPhoto.Image.Height > picPhoto.Image.Width Then
            dZoomFactor = (pnlPhoto.Height - 5) / picPhoto.Image.Height
            dZoomFactor = (pnlPhoto.Width - 5) / picPhoto.Image.Width
        End If

    End Sub

We will now modify the event handler that responds to a double click on a thumbnail so that the photo displayed will be resized to fit the screen.  Alter the event handler so it looks like this:

    Private Sub OnThumbnailDoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim tnThumbnail As Thumbnail
        If sender.GetType Is GetType(Thumbnail) Then
            tnThumbnail = DirectCast(sender, Thumbnail)
            picPhoto.Image = Bitmap.FromFile(tnThumbnail.FileName)
            ReDrawPhoto(0, 0)
        End If
    End Sub

We are now ready to add mouse wheel zooming to the application.  We need to add two event handlers, one to set the focus to the photo if it is clicked on - the photo must have focus to raise a MouseWheel event.  The zoom event handler simply checks whether the user is scrolling forwards or backwards and adjusts the zoom factor accordingly and redraws the photo.  We adjust the zoom factor by multiplying it by either "1 + dZoomIncrements" or "1 - dZoomIncrements", i.e. 1.15 or 0.85 so we increase or decrease the zoom factor by 15% of its current value after each operation.  When we call the ReDrawPhoto function we will pass in the position of the mouse on the panel - these coordinates include any portion image currently not visible.  The event handlers are shown below.

     Private Sub picPhoto_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
        Handles picPhoto.MouseWheel

        If e.Delta > 0 Then
            dZoomFactor *= (e.Delta / 120) * (1 + dZoomIncrements)
        ElseIf e.Delta < 0 Then
            dZoomFactor *= (e.Delta / -120) * (1 - dZoomIncrements)
        End If
        ReDrawPhoto(e.X, e.Y)
    End Sub

    Private Sub picPhoto_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles picPhoto.Click
    End Sub

It should be noted that this method of mouse wheel zooming is not perfect.  When the user scrolls the mouse wheel the panel that contains the picture is vertically scrolled before the MouseWheel event fires.  As a result the location to keep in the centre of the screen that is passed to the ReDrawPhoto function is not always the area the user had the mouse over, but instead a position either slightly above or below the target area.

Sponsored Links