Optimal Image Resizing Technique (Critique)
This is an optimal image resizing procedure that took me a lot of time/research to create. I hope you find it useful. LMK what you think.
This is flexible, and I'm sure there was a more efficient way to write it, but I'll explain. You can specify a max width without a max height. You can specify a max height without a max width by setting maxWidth to 0 (default optional value).
ResizeImage(imgFilepath, 300)
This would resize 600x400 to 300x200
This would resize 400x600 to 300x450
ResizeImage(imgFilepath, 300, 300)
This would resize 600x400 to 300x200
This would resize 400x600 to 200x300
ResizeImage(imgFilepath, 0, 300)
This would resize 600x400 to 450x300
This would resize 400x600 to 200x300
This provides the flexibility to maintain image proportion and if you need all images to be a certain width or a certain height where the opposite dimension doesn't matter.
Of course you can't do both, or you would have to alter the proportions of the image, and this procedure will never do that.
Also, you may want to change the bolded encoder paraemter for quality to 100L. I have it lowered so that the images take up less disk space, something I'm more concerned with.
This is an optimal technique because it uses proper canvasing and rendering and it maintains proper codec and parameter information for jpeg, gif, tiff, png, etc. Otherwise your images start to lose compatability as they may not be true jpeg's or gif's, which they aren't if they have a bad codec.
Code:
Public Shared Sub ResizeImage(ByVal imageFilepath As String, Optional ByVal maxWidth As Integer = 0, Optional ByVal maxHeight As Integer = 0)
Dim imgIn As Drawing.Bitmap = Drawing.Image.FromFile(imageFilepath)
Dim imgResized As Drawing.Bitmap
Dim newSize As New Drawing.Size
Dim oldSize As New Drawing.Size(imgIn.Width, imgIn.Height)
Dim ratio As Decimal
If oldSize.Height > oldSize.Width Then
ratio = maxHeight / oldSize.Height
If oldSize.Width * ratio > maxWidth Then ratio = maxWidth / oldSize.Width
newSize.Height = CInt(oldSize.Height * ratio)
newSize.Width = CInt(oldSize.Width * ratio)
Else
ratio = maxWidth / oldSize.Width
If oldSize.Height * ratio > maxHeight Then ratio = maxHeight / oldSize.Height
newSize.Width = CInt(oldSize.Width * ratio)
newSize.Height = CInt(oldSize.Height * ratio)
End If
imgResized = New Drawing.Bitmap(newSize.Width, newSize.Height, Drawing.Imaging.PixelFormat.Format24bppRgb)
Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(imgResized)
g.FillRectangle(Drawing.Brushes.White, 0, 0, newSize.Width, newSize.Height)
g.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
g.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
g.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
g.DrawImage(imgIn, 0, 0, newSize.Width, newSize.Height)
imgResized.SetResolution(72, 72)
Dim encoderParams As New Drawing.Imaging.EncoderParameters(1)
Dim param As New Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L)
encoderParams.Param(0) = param
Dim codecInfo() As Drawing.Imaging.ImageCodecInfo = Drawing.Imaging.ImageCodecInfo.GetImageEncoders
Dim codecNum As Integer
Dim extension As String
With imgIn.RawFormat
If .Equals(Drawing.Imaging.ImageFormat.Bmp) Then
codecNum = 0
extension = ".bmp"
ElseIf .Equals(Drawing.Imaging.ImageFormat.Jpeg) Then
codecNum = 1
extension = ".jpeg"
ElseIf .Equals(Drawing.Imaging.ImageFormat.Gif) Then
codecNum = 2
extension = ".gif"
ElseIf .Equals(Drawing.Imaging.ImageFormat.Tiff) Then
codecNum = 3
extension = ".tiff"
ElseIf .Equals(Drawing.Imaging.ImageFormat.Png) Then
codecNum = 4
extension = ".png"
Else
codecNum = 1
extension = ".jpeg"
End If
End With
imgIn.Dispose()
IO.File.Delete(imageFilepath)
imageFilepath = imageFilepath.Substring(0, imageFilepath.LastIndexOf(".")) & extension
imgResized.Save(imageFilepath, codecInfo(codecNum), encoderParams)
imgResized.Dispose()
End Sub