Resize an image in VB.NET without XAML

Overview

Want to resize an image while keeping the aspect ratio in a VB.NET WPF class? This class inspects the image to see if the width or height is larger, then uses the larger percent to so the resize.

Next, it compares the DPI of the original image to the Monitors DPI, and calculates the new pixel size. Then returns the new imagesource. I used PNG because it has a small memory overhead, and it supports transparency. You can choose any encoder you want though.

Public Function ResizeImage(ByVal ImageSource As ImageSource, ByVal MaxSize As Size) As ImageSource
        If ImageSource Is Nothing Then
            Return Nothing
        End If



        ' First we find the biggest gap between the original image size and the max size.
        Dim paWidth As Double = ImageSource.Width - MaxSize.Width
        Dim paHeight As Double = ImageSource.Height - MaxSize.Height

        Dim ShrinkPercent As Double = 0.0

        ' Calculate the amount to shrink using the bigger amount in height or width. Then get the percentage of the shrinkage.
        If paHeight > paWidth Then
            ShrinkPercent = ImageSource.Height / MaxSize.Height
        ElseIf paWidth > paHeight Then
            ShrinkPercent = ImageSource.Width / MaxSize.Width
        End If


        '*** Uncomment the debug lines to see how the conversion is made. ***

        'Debug.WriteLine("The shrink percent is:" & ShrinkPercent)
        'Debug.WriteLine("The new size proposed is:" & ImageSource.Width / ShrinkPercent & "x" & ImageSource.Height / ShrinkPercent)



        ' Deep copy the image so we can create a new one.
        Dim scr = CType(ImageSource, BitmapImage)
        Dim stream As New MemoryStream
        Dim encoder As New PngBitmapEncoder
        encoder.Frames.Add(BitmapFrame.Create(ImageSource))
        encoder.Save(stream)
        stream.Flush()

        ' Load the file data from the deep copy.
        Dim imageBytes As Byte() = stream.ToArray


        ' This is not necessary. I use this to see what the DPI settings for the monitor are at the moment.
        Dim x As New BitmapImage
        x.BeginInit()
        stream.Seek(0, IO.SeekOrigin.Begin)
        x.StreamSource = stream
        x.EndInit()

        
        ' Using the temporary image above and the DPI settings from the source image. I create a new image.

        ' ImageSource.Width / ShrinkPercentage = How many pixels to subtract from the image width
        ' scr.DpiY / x.DpiY = The image may have a different DPI, so we use this to convert it to the DPI we are using.
        ' Notice the 'x' is a temporary image I've created. You can use 96 instead. Windows blindly uses this for it's setting.
        Dim imageSrc As BitmapSource = CreateImage(imageBytes, _
                                                   (ImageSource.Width / ShrinkPercent) * (scr.DpiY / x.DpiY), _
                                                   (ImageSource.Height / ShrinkPercent) * (scr.DpiX / x.DpiX))


        'Debug.WriteLine("Created Image size:" & imageSrc.Width & "x" & imageSrc.Height)
        'Debug.WriteLine("Created Image Pixel size:" & imageSrc.PixelWidth & "x" & imageSrc.PixelHeight)

        Return imageSrc
    End Function

    
    ' The following function was taken from the web. Sorry, I forgot the source.

    Private Function CreateImage(ByVal imageData As Byte(), ByVal decodePixelWidth As Integer, ByVal decodePixelHeight As Integer) As BitmapSource
        If imageData Is Nothing Then
            Return Nothing
        End If

        Dim result As New BitmapImage()
        result.BeginInit()
        If decodePixelWidth > 0 Then
            result.DecodePixelWidth = decodePixelWidth
        End If
        If decodePixelHeight > 0 Then
            result.DecodePixelHeight = decodePixelHeight
        End If
        result.StreamSource = New MemoryStream(imageData)
        result.CreateOptions = BitmapCreateOptions.None
        result.CacheOption = BitmapCacheOption.[Default]
        result.EndInit()
        Return result
    End Function

More by this Author


Comments 1 comment

Dennis 4 years ago

Nice Snippet, but you made one Mistake. If the height and width are the same. ShrinkPercent will result in an zero, leading to an overflowexception.

So use this:

If paHeight is greater or equal paWidth Then

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working