Полезное⚜️
December 22, 2024
Замена даты создания файла на exif
Несколько лет назад я потерял все свои фотографии, которые хранил на внешнем жестком диске. Для упорядочивания файлов было написано несколько скриптов, и этот один из них.
Скрипт ищет дату создания фотографии (её проставляет фотоаппарат) и подставляет в поле "создано".
Важно: Для работы со свойствами EXIF в PowerShell используется класс[System.Drawing.Bitmap]
, являющийся частью .NET Framework. Однако в некоторых современных версиях PowerShell этот класс может быть не доступен по умолчанию.
Если при запуске скрипта возникнут ошибки, убедитесь, что у вас установлена .NET Framework (Windows PowerShell 5.1 обычно идет вместе с .NET Framework) или используйте другой способ чтения EXIF (например, утилитуexiftool
).
#requires -version 3 <# .SYNOPSIS Скрипт рекурсивно ищет файлы изображений, получает EXIF-дату (дата/время съемки) и ставит её в качестве даты создания файла. Если EXIF не найдена – выводит имя файла в консоль. .DESCRIPTION 1. Рекурсивно обходит все подпапки в указанных путях (по умолчанию - текущая директория). 2. Ищет файлы изображений по заданным расширениям: jpg, jpeg, png, gif, tiff, bmp. 3. С помощью .NET-класса [System.Drawing.Bitmap] считывает EXIF-свойства. 4. Берёт значение EXIF-тега DateTimeOriginal (Id 0x9003), парсит его в дату и назначает её как CreationTime и LastWriteTime файла. 5. Если EXIF-дата отсутствует, выводит сообщение в консоль и ничего с файлом не делает. .NOTES Автор: ChatGPT (пример) Требования: - PowerShell 3.0+ - .NET Framework (для класса System.Drawing.Bitmap) #> param( [Parameter(Mandatory=$false, Position=0)] [string] $Path = "." ) # Подключаем сборку System.Drawing, если она ещё не загружена. # В некоторых окружениях (например, Windows PowerShell 5.1) достаточно, в других может быть недоступна. try { Add-Type -AssemblyName System.Drawing } catch { Write-Host "Не удалось загрузить сборку System.Drawing. Убедитесь, что установлена .NET Framework или попробуйте другой метод чтения EXIF." -ForegroundColor Red return } # Список расширений, которые считаем изображениями $imageExtensions = '.jpg', '.jpeg', '.png' # Получаем список всех файлов с нужными расширениями рекурсивно из каталога $Path Write-Host "Поиск изображений в папке: $Path`..." $files = Get-ChildItem -Path $Path -Recurse -File | Where-Object { $imageExtensions -contains $_.Extension.ToLower() } if ($files.Count -eq 0) { Write-Host "Не найдено файлов с расширениями: $($imageExtensions -join ', ')" return } foreach ($file in $files) { try { $bitmap = New-Object System.Drawing.Bitmap($file.FullName) # Ищем EXIF-тег DateTimeOriginal (0x9003). # Для некоторых снимков старых форматов может использоваться 0x0132 (DateTime) или 0x9004 (DateTimeDigitized). # Но самый распространённый - 0x9003 (DateTimeOriginal). $exifItem = $bitmap.PropertyItems | Where-Object { $_.Id -eq 0x9003 } if ($exifItem) { # EXIF-дата хранится как ASCII-строка формата "yyyy:MM:dd HH:mm:ss" $exifDateString = [System.Text.Encoding]::ASCII.GetString($exifItem.Value).Trim([char]0) if ([string]::IsNullOrWhiteSpace($exifDateString)) { Write-Host "EXIF-дата отсутствует (пустая) в файле: $($file.FullName)" $bitmap.Dispose() continue } # Парсим дату. Формат обычно: "YYYY:MM:dd HH:mm:ss" $format = "yyyy:MM:dd HH:mm:ss" $exifDate = [datetime]::ParseExact($exifDateString, $format, $null) # Устанавливаем дату создания (CreationTime) и дату изменения (LastWriteTime) файла [System.IO.File]::SetCreationTime($file.FullName, $exifDate) [System.IO.File]::SetLastWriteTime($file.FullName, $exifDate) # (опционально) Можете оставить только CreationTime или только LastWriteTime # [System.IO.File]::SetCreationTime($file.FullName, $exifDate) Write-Host "Обновлена дата для: $($file.FullName) => $exifDate" } else { Write-Host "EXIF-дата не найдена в файле: $($file.FullName)" } $bitmap.Dispose() } catch { Write-Warning "Ошибка при обработке файла $($file.FullName). Текст ошибки: $_" } }
Для запуска надо сохранить скрипт в файл, например в Set-ExifDate.ps1. Пример команды для запуска:
.\Set-ExifDate.ps1 -Path "C:\MyPhotos"