Created
September 3, 2022 18:43
-
-
Save obsti8383/bcc67098bdc6fca65b05720da8b20d84 to your computer and use it in GitHub Desktop.
renamePictures PowerShell Script using exiftool
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
# Example calls: | |
# ./renamePictures.ps1 | |
# ./renamePictures.ps1 -defaultDescription Holland2022 | |
# ./renamePictures.ps1 -fixedDescription Hallo123 | |
# ./renamePictures.ps1 -folder hallo\. -defaultDescription Holland2022 | |
param( | |
[string]$folder=".", | |
[switch]$simulate, | |
[switch]$removeExistingDates, | |
[switch]$dontUseDescription, | |
[string]$defaultDescription, | |
[string]$fixedDescription | |
) | |
## needs exiftool! ## | |
# Windows: winget install exiftool | |
# Linux SUSE: sudo zypper in exiftool | |
# Linux APT: sudo apt-get install exiftool | |
$ErrorActionPreference = "Stop" | |
$picFilter = 'JPG|GIF|PNG|JPEG' | |
function renameRecursively { | |
param ( | |
[System.IO.FileSystemInfo]$file, | |
[string]$newName, | |
[int]$counter | |
) | |
if ( $counter -ne 0 ){ | |
$destName = $newName + "_" + $counter + $file.Extension | |
} else { | |
$destName = $newName + $file.Extension | |
} | |
if ($destName -eq $file.FullName){ | |
# nothing to do, file already has correct name | |
Write-Host "Nothing to do" #$destName -ForegroundColor Green | |
return | |
} | |
if (-not(Test-Path -Path $destName)) { | |
Write-Host $destName -ForegroundColor Cyan | |
Move-Item $file.FullName $destName | |
} else { | |
$counter++ | |
renameRecursively -file $file -newName $newName -counter $counter | |
} | |
} | |
function getExifTool(){ | |
if($IsLinux){ | |
# assume exiftool is in path in Linux OS | |
return "exiftool" | |
} | |
# first check if exiftool.exe is in same directory as this script | |
$exiftool = $PSScriptRoot+"\exiftool.exe" | |
if (Test-Path -Path $exiftool){ | |
return $exiftool | |
} | |
# Then check for %LocalAppData%\Programs\ExifTool | |
$exiftool = $Env:LocalAppData+"\Programs\ExifTool\ExifTool.exe" | |
if (Test-Path -Path $exiftool){ | |
return $exiftool | |
} | |
Write-Host "Searching for exiftool binary on %LocalAppData%. This might take a while..." | |
$exiftools = Get-Childitem -Path $Env:LocalAppData\ -Include exiftool.exe -Force -Recurse -File -ErrorAction SilentlyContinue | |
# just use the first one | |
if ($exiftools -ne $null -and $exiftools[0] -ne $null){ | |
Write-Host "Found "+$exiftools[0].FullName | |
return $exiftools[0].FullName | |
} | |
Write-Host "Searching for exiftool binary on C:\. This might take a while..." | |
$exiftools = Get-Childitem -Path C:\ -Include exiftool.exe -Force -Recurse -File -ErrorAction SilentlyContinue | |
# just use the first one | |
if ($exiftools -ne $null -and $exiftools[0] -ne $null){ | |
Write-Host "Found "+$exiftools[0].FullName | |
return $exiftools[0].FullName | |
} else { | |
Write-Host "No exiftool.exe found, aborting..." | |
exit 1 | |
} | |
} | |
$exiftool = getExifTool | |
Write-Host "Using exiftool binary: " + $exiftool | |
# check input parameters | |
if($dontUseDescription -eq $false -and $defaultDescription -eq ""){ | |
$defaultDescription = Read-Host "Please enter default description for filename > " | |
#Write-Host "Error: Please always use '-defaultDescription' when using descriptions in filenames. Otherwise use '-dontUseDescription'" | |
#exit 1 | |
} | |
# get all files, filtered by the common picture types | |
$files = Get-ChildItem $folder -File | Where-Object { $_.Extension -match $picFilter } | |
ForEach ($file in $files) { | |
Write-Host $file.FullName "`t->`t" -ForegroundColor Cyan -NoNewLine | |
# get DateTimeOriginal from EXIF data | |
$takenData = (& $exiftool -ignoreMinorErrors -DateTimeOriginal -s -s -s $file.FullName) | |
try { | |
$date = [DateTime]::ParseExact($takenData, 'yyyy:MM:dd HH:mm:ss', $null) | |
} | |
catch { | |
# ignore error, do nothing | |
} | |
if ($null -eq $date) { | |
Write-Host 'Error: No ''Date Taken'' in Exif' -ForegroundColor Cyan | |
} | |
else { | |
$newname = $file.BaseName | |
if ("" -ne $fixedDescription) { | |
# set new file name with fixed description | |
$newname = $fixedDescription | |
} | |
if (-not($dontUseDescription)) { | |
# set new file name with description from metadata | |
$description = (& $exiftool -ignoreMinorErrors -ImageDescription -s -s -s $file.FullName) | |
if ($null -eq $description -or "" -eq $description ) { | |
$description = (& $exiftool -ignoreMinorErrors -xmp:description -s -s -s $file.FullName) | |
if ($null -eq $description -or "" -eq $description ) { | |
$description = $defaultDescription | |
} | |
} | |
$newname = $description | |
$newname = $newname -replace '[^a-zA-Z0-9_\.]', '' # remove all non wanted special characters | |
} | |
if ($removeExistingDates) { | |
# remove existing numbers and underscores that are 6 chars or longer | |
$newname = $newname -replace '[0-9_-]{6,}', '' | |
} | |
# add date+time in front of new name | |
$newName = $date.ToString('yyyyMMdd_HHmmss_') + $newname | |
# create full path (incl. directory name) | |
$newName = (Join-Path $file.DirectoryName $newName) | |
if ( $false -eq $simulate ) { | |
renameRecursively -file $file -newname $newName | |
} else { | |
# only output filename in case of simulation | |
# important: does not consider filename conflicts | |
$destName = $newName + $file.Extension | |
Write-Host $destName -ForegroundColor Cyan | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment