Resize an Image in Windows 8/8.1 --- with PowerShell!

January 8, 2015 by Christopher Walker

A couple of days ago I had an image that was too big for the context I wanted to use it in. I needed to shrink it down to about 50% of its size. Typically I have access to Windows Picture Manager but unfortunately it was removed from the Office 2013 suite.

The options I received online were either use Paint, download a Windows App from the Windows Store, or download a third-party tool on the Internet.

I tried Paint to no avail. The resized image turned out horribly.

I searched for a Windows App but all I could find were either free apps that you could only share to a social media network or paid apps. I didn’t want to pay for such a simple task.

I didn’t try to download one off the internet because by the time I finished with the Windows Store I had resolved to try and do it in PowerShell. As I searched Google, lo and behold I was guided to a quick little .Net code block that led me in the right path.

After sitting down for a bit to hack it out and test, I came to my final CmdLet called “Resize-Image”. The following is what I came up with:


<#
.SYNOPSIS
   Resize an image
.DESCRIPTION
   Resize an image based on a new given height or width or a single dimension and a maintain ratio flag. 
   The execution of this CmdLet creates a new file named "OriginalName_resized" and maintains the original
   file extension
.PARAMETER Width
   The new width of the image. Can be given alone with the MaintainRatio flag
.PARAMETER Height
   The new height of the image. Can be given alone with the MaintainRatio flag
.PARAMETER ImagePath
   The path to the image being resized
.PARAMETER MaintainRatio
   Maintain the ratio of the image by setting either width or height. Setting both width and height and also this parameter
   results in an error
.PARAMETER Percentage
   Resize the image *to* the size given in this parameter. It's imperative to know that this does not resize by the percentage but to the percentage of
   the image. 
.EXAMPLE
   Resize-Image -Height 45 -Width 45 -ImagePath "Path/to/image.jpg"
.EXAMPLE
   Resize-Image -Height 45 -MaintainRatio -ImagePath "Path/to/image.jpg"
.EXAMPLE
   #Resize to 50% of the given image
   Resize-Image -Percentage 50 -ImagePath "Path/to/image.jpg"
.NOTES
   Written By: 
   Christopher Walker
#>
Function Resize-Image() {
    [CmdLetBinding(
        SupportsShouldProcess=$true, 
        PositionalBinding=$false,
        ConfirmImpact="Medium",
        DefaultParameterSetName="Absolute"
    )]
    Param (
        [Parameter(Mandatory=$True)]
        [ValidateScript({
            $_ | ForEach-Object {
                Test-Path $_
            }
        })][String[]]$ImagePath,
        [Parameter(Mandatory=$False)][Switch]$MaintainRatio,
        [Parameter(Mandatory=$False, ParameterSetName="Absolute")][Int]$Height,
        [Parameter(Mandatory=$False, ParameterSetName="Absolute")][Int]$Width,
        [Parameter(Mandatory=$False, ParameterSetName="Percent")][Double]$Percentage
    )
    Begin {
        If ($Width -and $Height -and $MaintainRatio) {
            Throw "Absolute Width and Height cannot be given with the MaintainRatio parameter."
        }

        If (($Width -xor $Height) -and (-not $MaintainRatio)) {
            Throw "MaintainRatio must be set with incomplete size parameters (Missing height or width without MaintainRatio)"
        }

        If ($Percentage -and $MaintainRatio) {
            Write-Warning "The MaintainRatio flag while using the Percentage parameter does nothing"
        }
    }
    Process {
        ForEach ($Image in $ImagePath) {
            $Path = (Resolve-Path $Image).Path
            $Dot = $Path.LastIndexOf(".")
            #Add name modifier (OriginalName_resized.jpg)
            $OutputPath = $Path.Substring(0,$Dot) + "_resized" + $Path.Substring($Dot,$Path.Length - $Dot)
            $OldImage = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $Path
            $OldHeight = $OldImage.Height
            $OldWidth = $OldImage.Width

            If ($MaintainRatio) {
                $OldHeight = $OldImage.Height
                $OldWidth = $OldImage.Width
                If ($Height) {
                    $Width = $OldWidth / $OldHeight * $Height
                }
                If ($Width) {
                    $Height = $OldHeight / $OldWidth * $Width
                }
            }

            If ($Percentage) {
                $Percentage = ($Percentage / 100)
                $Height = $OldHeight * $Percentage
                $Width = $OldWidth * $Percentage
            }

            $Bitmap = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $Width, $Height
            $NewImage = [System.Drawing.Graphics]::FromImage($Bitmap)
            
            #Retrieving the best quality possible
            $NewImage.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality
            $NewImage.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
            $NewImage.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
            
            $NewImage.DrawImage($OldImage, $(New-Object -TypeName System.Drawing.Rectangle -ArgumentList 0, 0, $Width, $Height))
            If ($PSCmdlet.ShouldProcess("Resized image based on $Path", "saved to $OutputPath")) {
                $Bitmap.Save($OutputPath)
            }
            $Bitmap.Dispose()
            $NewImage.Dispose()
        }
    }
}

Get the Gist of this CmdLet on GitHub

If help is needed on understanding how to use it, either read the comments above the function or type Get-Help Resize-Image

Privacy Policy

© 2017 | Powered by Hugo and lots of motivation.