![RenomearFromExif.ps1](https://rvso.com/image/1465785/RenomearFromExif.ps1.png)
Tenho uma pasta com fotos tiradas com câmeras diferentes e todas essas fotos estão corretasDataHoraOriginalConjunto de tags EXIF.
Suponha uma lista de arquivos como esta:
20150831_153712.jpg
IMG_5246.JPG
IMG_5247.JPG
20150902_201425.jpg
Agora gostaria de saber como renomear esses arquivos desta forma, com base noDataHoraOriginaletiqueta, é claro:
001_IMG_5246.JPG
002_20150831_153712.jpg
003_IMG_5247.JPG
004_20150902_201425.jpg
Basicamente eu queroexiftool(ou um programa em lote do Windows, se isso não for possível diretamente) paraorganizartoda a pasta de JPEGs porDataHoraOriginalascendente e a operação de renomeação deve colocar umcontadorprefixo na frente do nome do arquivo (mantendo assim o nome do arquivo original).
Também gostaria de saber como fazercomando de teste para visualizar a renomeaçãoantes que ocorra (para ver se algo está errado, suponho que usando oNome de testemarcação).
Responder1
Os itens que você deseja usar com o ExifTool são as -FileOrder
opções e a FileSequence
tag, além de um pouco de Perl usando a opção de formatação avançada. A opção FileOrder classificará os arquivos com base na hora listada com a opção. Isso torna o ExifTool um pouco mais lento, porque ele precisa ler cada arquivo duas vezes, mas ainda é geralmente mais rápido do que outras opções, como fazer loop e chamar o ExifTool para cada loop. A tag FileSequence é interna ao ExifTool e controla o número do arquivo que está sendo processado no momento. Começa em 0, então teremos que adicionar 1 no processamento avançado. É também onde preencheremos os zeros para que tenham pelo menos 3 caracteres.
Experimente este comando:
ExifTool "-TestName<${FileSequence;$_=0 x(3-length($_+1)).($_+1)}_$filename" -FileOrder DateTimeOriginal DIR
Se funcionar, basta substituir -TestName
por -FileName
:
ExifTool "-FileName<${FileSequence;$_=0 x(3-length($_+1)).($_+1)}_$filename" -FileOrder DateTimeOriginal DIR
Para alterar o número de zeros preenchidos, altere 3 3-length
para o número desejado. Para alterar o número inicial, altere 1 em $_+1
.
Responder2
Eu verifiquei algumas ferramentas de renomeação. O principal problema é que ferramentas comoRenomear MestreeFerramenta Exifpode acessar dados EXIF. Mas não consegui encontrar uma maneira de gerar uma lista numerada.
Então escrevi um script do PowerShell para fazer isso. Comentei cada linha. Deve ser fácil de entender. Basta lê-los.
A primeira coisa que tive que fazer foi pesquisarID de "DateTimeOriginal"então podemos usar GetPropertyItem(MyExifID)
. Em segundo lugar, adicionamos todas as imagens de uma determinada pasta que na verdade possui um DateTimeOriginal a um array. A partir daqui foi fácil. Classificamos o array por coluna de data, incrementamos um contador simples e construímos nosso novo nome de arquivo com o padrão 000_oldname
.
Este script não modificará nada.Ele só produz algo como:
Use-o para verificar o que o script faria. Depois de verificar os resultados possíveis, remova o indicador de comentário #
antes da linha #Rename-Item $_[0].Fullname $newName
.De agora em diante, o script renomeará seus arquivos de acordo.
RenomearFromExif.ps1
# Set image folder to process
$strDirectory = "T:\Pictures"
# Create empty array
$arrSortMe = @()
# Load Windows library to access EXIF data
[void][Reflection.Assembly]::LoadWithPartialName("System.Drawing")
# Loop through all JPGs and JPEGs in the given image folder
Get-ChildItem -Path "$strDirectory\*" -Include *.jpg,*.jpeg | ForEach {
# Load current image into Powershell as bitmap object
$img = New-Object -TypeName system.drawing.bitmap -ArgumentList $_.FullName
# Error handling for images which doesn't have the specified EXIF data
Try {
# Get EXIF data with ID 36867 - which is "DateTimeOriginal"
$intExif = [Byte[]]$img.GetPropertyItem(36867).Value
# Release image or else later we can't rename it
$img.Dispose()
# Convert EXIF data from byte array to string
$strExif = [System.Text.Encoding]::Default.GetString($intExif, 0, $intExif.Length-1)
# Convert EXIF data from string to datetime
$dateExif = [DateTime]::ParseExact($strExif, 'yyyy:MM:dd HH:mm:ss', $null)
# Add to multidimensional array: [0]=current_file and [1]=datetime
$arrSortMe += ,@($_, $dateExif)
}
Catch {}
}
Write-host "DateTimeTaken" `t`t`t "New Name" `t`t`t "Old Fullname"
# Sort array by datetime and pipe the sorted array to a foreach loop
$arrSortMe | Sort-Object @{Expression={$_[1]} } | ForEach {$i=0}{
# Increment a simple counter starting with 0, so the first image gets the "1"
$i++
# Format the counter to 3-digits, append an underscore followed by the old image name
$newName = $i.ToString("000") + "_" + $_[0].Name
# Don't rename images which already have three digits as filename start
If ($_.Name -notmatch "^[\d]{3}_") {
#Rename-Item $_[0].Fullname $newName
}
# Only for debugging
Write-host $_[1].Date `t $newName `t $_[0].Fullname
}
# Clear all variables. System variables are readonly so we don't mind using * to get all
Remove-Variable * -ErrorAction SilentlyContinue
Recursos usados
- http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html
- http://blogs.technet.com/b/jamesone/archive/2007/07/13/exploring-photographic-exif-data-using-powershell-of-course.aspx
- http://blog.cincura.net/233463-renaming-files-based-on-exif-data-in-powershell/
- http://www.happysysadm.com/2011/01/multidimensional-arrays-in-powershell.html
- http://www.orcsweb.com/blog/james/fun-with-powershell-sorting-multidimensional-arrays-and-arraylists/
- http://blogs.technet.com/b/heyscriptingguy/archive/2008/06/02/hey-scripting-guy-how-can-i-use-leading-zeroes-when-displaying-a-value-in- windows-powershell.aspx