PowerShell and ImageMagick

I've been toying with Script-Fu (i.e. Scheme) combined with GIMP running in batch mode.
I had some success, but ran into a roadblock when it came to selecting individual pages from TIFF files. It was probably possible, but then I learned about ImageMagick.

After a few hours with PowerShell, I wrote the following script, which takes 4 parameters.

  • -SourcePath = Path to source images
  • -DestPath = Path where converted images should be stored
  • -NewType = One of several, known file types. I am handling these in PowerShell as I don't know all of ImageMagick's capabilities. Easier to handle errors in PowerShell than ImageMagick return codes in either case.
  • -SourceFrame (optional) = the number of the frame in the source image. For my multi-page TIFF files, I want the first frame (0).
Here's the code. It's not elegant, and it's a bit chatty with all my debug messages, but it works.

Next I'll wrap it in some more PowerShell to iterate through folders of images. Right now it only works on a single folder at a time.

#START POWERSHELL SCRIPT
param([parameter(Mandatory=$true)][string]$SourcePath, [parameter(Mandatory=$true)][string]$DestPath, [parameter(Mandatory=$true)][string]$NewType, [parameter()][int]$SourceFrame=0)

Function ConvertImages([parameter(Mandatory=$true)][string]$SourcePath, [parameter(Mandatory=$true)][string]$DestPath, [parameter(Mandatory=$true)][string]$NewType, [parameter(Mandatory=$true)][int]$SourceFrame)
{
#Check for required parameters before starting.
if (($NewType -ne $null) -and ($SourcePath -ne $null) -and ($DestPath -ne $null))
{

$NewType = "." + $NewType
$ChildSourceItems = $null #Contains an array of files found in $OrigRoot
$Item = $null #used to iterate through arrays of items
$ImageTypes = @(".xcf", ".jpg", ".jpeg", ".cr2", ".tif", ".tiff", ".png");

Write-Host "This scripts takes all the files in " $SourcePath ", converts them to " $NewType ", and stores them in " $DestPath ", creating the folder if it doesn't already exist."
#Fail gently if $SourcePath doesn't exist.
Write-Host "Checking for presence of " $SourcePath
if (!(Test-Path -path $SourcePath))
{
Write-Host $SourcePath " doesn't exist! Returning false."
return $false
}
#Fail a bit less gently if $NewType is unknown
if (!($ImageTypes -contains $NewType))
{
Write-Host $NewType " is not a known type. Known types are: " $ImageTypes
return $false
}

Write-Host "Checking for presence of " $DestPath
#Create $DestPathr if it doesn't already exist
if (!(Test-Path -path $DestPath))
{
Write-Host "Creating " $DestPath
New-Item $DestPath -type directory
}
#Call ImageMagick to perform conversion
DoMagick $SourcePath $SourceFrame $DestPath $NewType $ImageTypes

} Else
{
Write-Host "Required Parameters were null. Exiting."
}
}

Function DoMagick ([parameter(Mandatory=$true)][string]$SourcePath, [parameter(Mandatory=$true)][int]$SourceFrame, [parameter(Mandatory=$true)][string]$DestPath, [parameter(Mandatory=$true)][string]$NewType, [parameter(Mandatory=$true)][string[]]$ImageTypes)
{

Write-Host "I know all about " $ImageTypes
Write-Host "Getting Child Items of " $SourcePath
$ChildSourceItems = Get-ChildItem -Path $SourcePath
#Verify that we have some files to work with.
if ($ChildSourceItems.length -gt 0)
{
Write-Host "Found " $ChildSourceItems.length " items."
#Loop through and act on each file individually. Can't glob this part I'm afraid (ImageMagick globbing limitations on output file naming).
ForEach ($Item in $ChildSourceItems)
{
$ItemType = $Item.extension
Write-Host "Current Type is: "$ItemType
if ($ImageTypes -contains $ItemType)
{
$ItemFullName = $Item.Fullname + "[" + [string]$SourceFrame + "]"
Write-Host "Converting" $ItemFullName
$ItemNewName = $DestPath + "\" + $Item.Name.Replace($ItemType, $NewType)
Write-Host "The new name will be: " $ItemNewName
#Call ImageMagick command-line converter
& "convert" $ItemFullName $ItemNewName
} else
{
Write-Host "Unknown File Type" $Item.extension
}
}
} Else
{
Write-Host "There were no files in " $SourcePath " to process."
return false;
}
}


ConvertImages $SourcePath $DestPath $NewType $SourceFrame

#END POWERSHELL



Here's a sample invocation from a PowerShell:

./ConvertImages -SourcePath "c:\test\tiffs" -DestPath "c:\test\jpgs" -NewType "jpg" -SourceFrame 0

No comments:

Post a Comment