📷

ImageMagicで画像の一括リサイズ

に公開

高解像度の写真がオンプレのファイルSVの容量を圧迫していたので、条件指定したものをリサイズする方法を考えてみた。

使ったもの

実行する環境を汚したくないので、Portable版を今回は利用

処理の内容

PowerShellとImageMagicのコマンドを使って実装

  1. リサイズしたい画像があるフォルダを指定
  2. 指定したパスがあるか確認
  3. 指定したフォルダは以下で、対象となるファイルを検索して抽出
    ※スクリプト例では、1MB以上のサイズかつ拡張子が「jpg」を指定
  4. 画像データの撮影日時を取得 or 更新日時を取得(撮影日時がない場合の対応)
  5. ImageMagicでリサイズ
    ※縦か横が"1280"になるように指定している
  6. リサイズ時にファイル更新日時が更新されてしまうので、撮影日時(リサイズ前の更新日時)に修正

スクリプト

ImageResize.ps1
Add-Type -AssemblyName System.Drawing

$Input = Read-Host "リサイズしたい画像があるフォルダを指定"

if (Test-Path $Input) {
    # ImageMagickのディレクトリを指定
    Set-Location ".\ImageMagick"

    # 指定したフォルダ配下で1MB以上かつjpgのファイル抽出
    Get-ChildItem -Path "$Input" -Recurse |
    Where-Object { $_.Length -gt 1MB -and $_.Extension -eq ".jpg" } |
    ForEach-Object {
     
        # 対象画像ファイルを読み込み
        $Img = New-Object Drawing.Bitmap($_.FileName)
    
        # 画像ファイルの撮影日時を取得(バイト配列)
        $ByteAry = ($Img.PropertyItems | Where-Object{$_.Id -eq 36867}).Value

        # IsNullOrWhiteSpaceメソッドで空文字・空白のみ・Nullと「0000:00:00 00:00:00」チェック
       if(([System.String]::IsNullOrWhiteSpace($ByteAry)) -or ($ByteAry[0] = 48)) {
            # NULLなら更新日時を取得
            $BateStr =  (Get-ItemProperty $_.FileName).LastWriteTime

        } else {
            # yyyy:mm:dd hh:mm:ss → yyyy/mm/dd hh:mm:ss に変換
            $ByteAry[4] = 47
            $ByteAry[7] = 47
            
            # バイト配列を文字列に変換
            $DateStr = [System.Text.Encoding]::ASCII.GetString($ByteAry) 
        }
        
        # ファイルの読み込みの解放
        $Img.Dispose()
        $Img = $null
        
        # ImageMagickでリサイズ
        .\magick.exe mogrify -quality 100 -resize "1280x1280>" $_.FilellName
        
        # ファイル更新日時を撮影日時 or リサイズ前の更新日時に指定
        Set-ItemProperty $_.FileName -name LastWriteTime -value $DateStr
        }

} else {
    Write-Host "フォルダはありません"
}

BatからPowerShellを起動する場合はこんな感じで。

Start_ImageResize.bat
powershell -ExecutionPolicy RemoteSigned -File %~dp0ImageResize.ps1 > resize_error.log 2>&1

画像ファイルによってはエラーがでる場合もあるので、適宜調整していく。

補足

PropertyItem.Id プロパティ
https://learn.microsoft.com/ja-jp/dotnet/api/system.drawing.imaging.propertyitem.id?view=windowsdesktop-9.0&viewFallbackFrom=dotnet-plat-ext-8.0

Discussion