I knocked together this PowerShell script today to batch-convert 600+ staff photo images to B&W.
You’ll require the following items installed and in your path before this script will work:
- ImageMagick. I used the normal version, not one of the alternate ones.
- jhead: exif jpeg header manipulation tool. This requires ImageMagick in order to work.
ImageMagick does the actual conversion to B&W. I played with converting to pure grayscale, but it didn’t look good. This method instead strips out all colour information by setting saturation to zero:
convert.exe {sourcefile} -modulate 100,0 {destinationfile}
An issue I came across then is that ImageMagick doesn’t update the embedded JPG thumbnail. This issue almost stumped me, but then I came across this great little tool called jhead. Amongst other things, jhead can regenerate the JPG thumbnail (only if one existed originally):
jhead.exe -rgt {filename}
Tying it all together is PowerShell:
<# .SYNOPSIS Generate B&W versions of images Daniel Streefkerk THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER. Version 10, 02/08/2012 .DESCRIPTION This script runs though a folder full of images and creates B&W versions of said images IMPORTANT NOTE: This script requires ImageMagick and jhead. For more information, see my blog .PARAMETER RootFolder The folder within which to process images .PARAMETER Recursive Also scan subfolders? This is enabled by default .EXAMPLE Process all images in c:temp .Generate-BWImages.ps1 -RootFolder c:temp #> Param( [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='The folder that contains the photos')] [String] #[ValidateScript({Test-Path $_ -PathType 'Container'})] $RootFolder, [Parameter(Position=1,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Recurse through all subfolders?')] [bool] $Recursive=$true ) cls # Change these if necessary $fileExtensions = "*.jpg" $fileNameSuffix = "_bw" # the text to be appended to the file name to indicate that it has been modified $files = $null; $fileCount = 0 # Check if the root folder is a valid folder. If not, try again. if ((Test-Path $RootFolder -PathType 'Container') -eq $false) { Write-Host "'$RootFolder' doesn't seem to be a valid folder. Please try again" -ForegroundColor Red break } # Get all image files in the folder if ($Recursive) { $files = gci $RootFolder -Filter $fileExtensions -File -Recurse } else { $files = gci $RootFolder -Filter $fileExtensions -File } # If there are no image files found, write out a message and quit if ($files.Count -lt 1) { Write-Host "No image files with extension '$fileExtensions' were found in the folder '$RootFolder'" -ForegroundColor Red break } # Loop through each of the files and process it foreach ($image in $files) { $newFilename = $image.DirectoryName + "" + $image.BaseName + $fileNameSuffix + $image.Extension $imageFullname = $image.FullName write-host "Processing image: $imageFullname" -ForegroundColor Green & convert.exe $image.FullName -modulate "100,0" $newFilename write-host "Updating embedded thumbnail for: $newFilename" -ForegroundColor Green & jhead.exe -rgt $newFilename $fileCount++ } Write-Host "$fileCount images processed" -ForegroundColor Yellow