Public/Tools/Resize-Image.ps1

function Resize-Image {
    <#
    .SYNOPSIS
        Resizes a [System.Drawing.Image] object to the given height with the same aspect ratio.
    .DESCRIPTION
        Resizes a [System.Drawing.Image] object to the given height with the same aspect ratio and outputs a new
        Image object which uses the same codec as the original image unless otherwise specified.
    .EXAMPLE
        PS C:\> $image = $camera | Get-Snapshot -Live | ConvertFrom-Snapshot | Resize-Image -Height 200 -DisposeSource
        Get's a live snapshot from $camera and converts it to a System.Drawing.Image object, resizes it to 200 pixels tall and disposes the original image.
    .OUTPUTS
        [System.Drawing.Image]
    .NOTES
        Don't forget to call Dispose() when you're done with the image!
    #>

    [CmdletBinding()]
    [OutputType([System.Drawing.Image])]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.Drawing.Image]
        $Image,
        
        [Parameter(Mandatory)]
        [int]
        $Height,

        [Parameter()]
        [long]
        $Quality = 95,

        [Parameter()]
        [ValidateSet('BMP', 'JPEG', 'GIF', 'TIFF', 'PNG')]
        [string]
        $OutputFormat,

        [Parameter()]
        [switch]
        $DisposeSource
    )

    process {
        if ($null -eq $Image -or $Image.Width -le 0 -or $Image.Height -le 0) {
            Write-Error 'Cannot resize an invalid image object.'
            return
        }
        
        [int]$width = $image.Width / $image.Height * $Height
        $bmp = [system.drawing.bitmap]::new($width, $Height)
        $graphics = [system.drawing.graphics]::FromImage($bmp)
        $graphics.InterpolationMode = [system.drawing.drawing2d.interpolationmode]::HighQualityBicubic
        $graphics.DrawImage($Image, 0, 0, $width, $Height)
        $graphics.Dispose()
        
        try {
            $formatId = if ([string]::IsNullOrWhiteSpace($OutputFormat)) {
                    $Image.RawFormat.Guid
                }
                else {
                    ([system.drawing.imaging.imagecodecinfo]::GetImageEncoders() | Where-Object FormatDescription -eq $OutputFormat).FormatID
                }
            $encoder = [system.drawing.imaging.imagecodecinfo]::GetImageEncoders() | Where-Object FormatID -eq $formatId
            $encoderParameters = [system.drawing.imaging.encoderparameters]::new(1)
            $qualityParameter = [system.drawing.imaging.encoderparameter]::new([system.drawing.imaging.encoder]::Quality, $Quality)
            $encoderParameters.Param[0] = $qualityParameter
            Write-Verbose "Saving resized image as $($encoder.FormatDescription) with $Quality% quality"
            $ms = [io.memorystream]::new()
            $bmp.Save($ms, $encoder, $encoderParameters)
            $resizedImage = [system.drawing.image]::FromStream($ms)
            Write-Output ($resizedImage)
        }
        finally {
            $qualityParameter.Dispose()
            $encoderParameters.Dispose()
            $bmp.Dispose()
            if ($DisposeSource) {
                $Image.Dispose()
            }
        }
        
    }
}