Last active
August 22, 2022 12:24
-
-
Save Timberfang/249e3a3093c7ecea0f0c56bf0793e185 to your computer and use it in GitHub Desktop.
Convert images to other formats using ImageMagick.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Set-StrictMode -Version 3.0 | |
#Requires -Version 5.1 | |
Function Invoke-Mogrify { | |
<# | |
.SYNOPSIS | |
Convert images to other formats using ImageMagick. | |
.DESCRIPTION | |
This function will convert given images into the specified format. | |
The converted images will be saved to the same location as the original images by default. | |
While PowerShell 5.1 is supported, use ofPowerShell 7 is strongly recommended due to a | |
large speed increase in image processing times. | |
.PARAMETER Path | |
Source directory or directories files will be taken from. | |
Must be a valid path that exists on the computer. | |
.PARAMETER Format | |
Target format for images. | |
.PARAMETER Destination | |
Destination directory converted images will be placed in. | |
.PARAMETER Filter | |
Regex Filter to search by for files to convert. | |
Use to only convert only certain files, instead of the full contents of the source folders. | |
.EXAMPLE | |
Invoke-Mogrify -Path $PSScriptRoot\Input -Destination $PSScriptRoot\Output -Format PNG | |
Convert all pictures from one folder into PNG images. | |
.EXAMPLE | |
Invoke-Mogrify -Path $PSScriptRoot\Input,~\Gallery,~\user\pictures -Destination $PSScriptRoot\Output -Format jpg | |
Convert all pictures from multiple folders into jpg images. | |
#> | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory,ValueFromPipeline)] | |
[string]$Path, | |
[Parameter(Mandatory)] | |
[string]$Format, | |
[string]$Destination = $Path, | |
[string]$Filter = '.' | |
) | |
begin { | |
Write-Verbose -Message "Checking for ImageMagick." | |
if ($null -eq (Get-Command "magick" -ErrorAction SilentlyContinue)) { | |
Throw "ImageMagick not installed. Please install ImageMagick." | |
} | |
else { | |
Write-Verbose -Message "ImageMagick is installed." | |
} | |
} | |
process { | |
foreach ($Directory in $Path) { | |
Write-Verbose -Message "Renaming .jfif & .jpeg files to .jpg." | |
Get-ChildItem $Directory\* -Include ('*.jfif', '*.jpeg') | Rename-Item -NewName { $_.Name -Replace "\.(jfif|jpeg)$", ".jpg" } | |
Write-Verbose -Message "Searching for files..." | |
Get-ChildItem $Directory\* -Filter "$Filter" -Recurse -Include "*.$Format" | Move-Item -Destination $Destination | |
} | |
<# ImageMagick normally converts ALL images, even if they are already in the target format. | |
This will reduce quality if converting to lossy formats such as jpg. | |
ImageMagick does not have a parameter to filter out images, so Where-Object is used. | |
This does run about 25% more slowly than sending all images to ImageMagick, unfortunately. | |
This can be fixed on systems running at least PowerShell 7, | |
as the command can then be run in parallel. #> | |
# Still want to support 5.1, so the script will fall back to a slower sequential method when needed. | |
Write-Verbose -Message "Converting images to $Format" | |
if ($PSVersionTable.PSVersion -ge 7) { | |
Get-ChildItem $Path\* | Where-Object { | |
$_.Extension -match 'jpg' -or 'png' -or 'heic' -or 'webp' -or 'tiff' -and | |
$_.Extension -notmatch "$Format" | |
} | Foreach-Object -ThrottleLimit 5 -Parallel { | |
magick mogrify -path $USING:Destination -format $USING:Format $_ -define preserve-timestamp=true | |
} | |
} | |
else { | |
Get-ChildItem $Path\* | Where-Object { | |
$_.Extension -match 'jpg' -or 'png' -or 'heic' -or 'webp' -or 'tiff' -and | |
$_.Extension -notmatch "$Format" | |
} | ForEach-Object { | |
magick mogrify -path $Destination -format $Format $_ -define preserve-timestamp=true | |
} | |
} | |
} | |
end { | |
Write-Verbose -Message "Images Converted." | |
Write-Output -InputObject (Get-ChildItem $Destination\*.$Format -File) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment