■ JPEG時刻補正ツールを作る #2

デジカメの時計、ずれていることが良くある。
先日も11分進んでいた。
デジカメだけ使うのであれば何とかなるが、これにスマホで撮った写真が混在すると、時系列がめちゃめちゃになってしまい
整理するのが面倒。
そこで、JPEGファイルの更新日時・Exifの撮影日時を一括で補正するツールを考えてみる。
※ 前回記事:JPEG時刻補正ツールを作る #1

本文中の "$" は半角で読み替えること。
掲載したプログラムは自己責任でご使用ください。


ソースコード

作成したソースコード(JpegTimeCorrection.ps1)は以下の通り。
Param (
  [Parameter(mandatory=$true)][String]$inputDir,
  [Parameter(mandatory=$true)][String]$outputDir,
  [Parameter(mandatory=$true)][Int]$CorrectionValue
)
Add-Type -AssemblyName "System.Drawing"

# 既に$idで指定したPropertyItemが存在する場合、そのPropertyItemは削除する。
# $imageオブジェクトより先頭のPropertyItemオブジェクトを返す。
function GetPropertyItem($image, $id)
{
  $item = $image.PropertyItems | Where-Object { $_.Id -eq $id }
  if($item -ne $null) {
    $image.RemovePropertyItem($id)
  }
  return $image.PropertyItems | Select-Object -First 1
}

# $imageオブジェクトにPropertyItemを登録する。
function SetPropertyItem($image, $id, $len, $type, $value)
{
  $item = GetPropertyItem -image $image -id $id
  $item.Id = $id
  $item.Len = $len
  $item.Type = $type
  $item.Value = $value
  $image.SetPropertyItem($item)
}

# $dateTimeで指定した撮影日時よりExif用配列データを取得する。
function getDateTimeValue($dateTime)
{
  $chars = $dateTime.ToString("yyyy:MM:dd HH:mm:ss").ToCharArray()
  $ascii = @()
  foreach($char in $chars)
  {
    $ascii += [Byte][Char]$char
  }
  $ascii += 0
  return $ascii
}

# $imageオブジェクトに撮影日時PropertyItemを登録する。
function SetDateTime($image, $dateTime)
{
  $value = getDateTimeValue -dateTime $dateTime
  SetPropertyItem -image $image -id 0x9003 -len 20 -type 2 -value $value
  SetPropertyItem -image $image -id 0x9004 -len 20 -type 2 -value $value
}

# Exif情報登録
# $inputFileで指定したファイルに$dateTimeで指定したExif撮影日時を付加し$outputDirへ保存する。
# 保存したファイルのフルパスを返す。
function SetExifInfo($inputFile, $outputDir, $dateTime)
{
  $image = New-Object System.Drawing.Bitmap($inputFile)
  # SetExifVersion -image $image
  SetDateTime -image $image -dateTime $dateTime

  $outputFile = Join-Path $outputDir (Split-Path $inputFile -Leaf)
  $image.Save($outputFile)

  $image.Dispose()

  return $outputFile
}


# メイン処理
$files = Get-ChildItem -Path $inputDir\*.* -Include *.jpg,*.jpeg

foreach ($file in $files)
{
  try {
    $fileDate = (Get-ItemProperty -Path $file).LastWriteTime.AddMinutes($CorrectionValue)
    $outputFile = SetExifInfo -inputFile $file.FullName -outputDir $outputDir -dateTime $fileDate
    Set-ItemProperty $outputFile -Name LastWriteTime -Value $fileDate
    Write-Host( "[OK] " + $file.Name + " " + $fileDate)
  } catch {
    Write-Host( "[ER] " + $file.Name + "`r`n" + $_)
  }
}

# ここまで

使い方

PowerShellで実行する。
書式:
./JpegTimeCorrection.ps1 (入力パス) (出力パス) (補正値)
例:
入力先 D:\temp\input、出力先 D:\temp\oupput、補正値 -11分 とする場合、
./JpegTimeCorrection.ps1 D:\temp\input D:\temp\output -11
PowerShellでスクリプトを実行するには権限変更が必要である。以下記事を参考してください。
※ 過去記事:PowerShell学習 #2:スクリプトを実行するには?


次作プログラム, PowerShell, Exif

0 件のコメント:

その他の記事