■ JPEG更新日時一括変更ツールを作る #6

#5 からの続き

概要

スキャンしたレシートをGoogleフォトにアップしているが、Googleフォトではファイルの更新日時(スキャンした日時)で分類されてしまう。
スキャン日時でなく、実際の利用日時で分類してほしい。
そこで、ファイル名に利用日時を付加しておき、ファイル更新日時を付加した日時で一括更新するツールを作成する。

本文中の "$" は半角で読み替えること。


今回の内容

前回までに作成したソースコードをまとめる。

ツールの使い方

ChangeJpegDate.ps1 (1:JPEGを格納したパス) (2:設定したJPEGファイルを格納するパス)
(1:JPEGを指定したパス)で指定したパス内のファイル名が "YYYYMMDD_HHMM_xxx.jpeg" の書式のファイルを取得、
ファイルの更新日時とExif撮影日時をファイル名の日時に置換する。
置換後のファイルは(2:設定したJPEGファイルを格納するパス)に保存する。
サブフォルダは検索対象外

ソースコード

ファイル名:ChangeJpegDate.ps1
(2020.09.17改版) 変数名ルール:"~Path"でなく"~Dir"へ統一 → $outputPath → $outputDirとする
(2020.09.17改版) 拡張子は "jpeg" または "jpg" どちらでも可能とするように修正
Param (
  [Parameter(mandatory=$true)][String]$inputDir,
  [Parameter(mandatory=$true)][String]$outputDir
)
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)
}

# $imageオブジェクトにExifバージョン(0210)をPropertyItemsに登録する。
function SetExifVersion($image)
{
  SetPropertyItem -image $image -id 0x9000 -len 4 -type 7 -value @(48,50,49,48)
}

# $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 | Where-Object {$_.Name -Match "^\d{8}_\d{4}_[^.]*\.(jpeg|jpg)"}

foreach ($file in $files)
{
  try {
    $fileDate = [DateTime]::ParseExact($file.Name.Substring(0, 13), "yyyyMMdd_HHmm", $null)
    $outputFile = SetExifInfo -inputFile $file.FullName -outputDir $outputDir -dateTime $fileDate
    Set-ItemProperty $outputFile -Name LastWriteTime -Value $fileDate
    Write-Host( "[OK] " + $file.Name)
  } catch {
    Write-Host( "[ER] " + $file.Name + "`r`n" + $_)
  }
}

# ここまで



-- 以上 --


自作プログラム, PowerShell, Exif
2020.09.17改版

0 件のコメント:

その他の記事