管理人Kのひとりごと

デジモノレビューやプログラミングや写真など

画像を縮小するスクリプト

もっぱら自分用に。ブログ用にバッチで縮小するスクリプトがほしかった。
PS D:\documents\scripts_work> .\resize.ps1 -overwrite y -longside 640 -filename "D:\Pictures\aaa.jpg"みたいな感じで。
※自動回転された画像に適用すると、回転が解除されることに気付いた...!! 要修正...
→修正しました

param(
[string]$filename,
[string]$longside=1280,
[string]$overwrite="n"
)

$ErrorActionPreference = "stop"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.IO")

# 保存用ファイルパス作成処理
# 引数1 :元画像ファイルのフルパス
# 引数2 :長辺ピクセル数
# 戻り値:<元ファイルのパス>「resized+長辺ピクセル数」<元ファイルの拡張子>
function script:GetNewFileName($originalFileName,$longside){
  # 元画像の格納ディレクトリを取得
  $private:path = [System.IO.Path]::GetDirectoryName($originalFileName)

  # 元画像のファイル名(拡張子除く)を取得
  $private:originalName = [System.IO.Path]::GetFileNameWithoutExtension($originalFileName)
  
  # 元画像の拡張子を取得(ピリオドは含まれる)
  $private:extensionName = [System.IO.Path]::GetExtension($originalFileName)
  
  # 回転後のファイル名(拡張子あり)を作成
  $private:newName = $originalName + "_resized" + $longside + $extensionName

  # 新ファイルパスを作成してリターン
  return [System.IO.Path]::Combine($path,$newName)
}

# リサイズ後サイズ計算処理(長辺ピクセル数をもとに、変更後ピクセル数を算出する)
# 引数1 :元画像ファイルBitmap
# 引数2 :長辺ピクセル数
# 戻り値:短辺ピクセル数
function script:CalcSize($sourceImage,$longside){
    $private:height = $sourceImage.height
    $private:width = $sourceImage.width
    $private:shortsize = 0

    # 小数点1位は四捨五入
    # 横 >= 縦
    if($width -ge $height){
      $shortsize = $height * ($longside / $width)
      $shortsize = [math]::Truncate($shortsize+.5)
    # 横 < 縦
    }else{
      $shortsize = $width * ($longside / $height)
      $shortsize = [math]::Truncate($shortsize+.5)
    }

    return $shortsize
}

# メイン処理
# 引数1 :長辺ピクセル数
# 引数2 :元画像ファイルのフルパス
# 引数3 :上書き(y) or コピー保存(n)
# 戻り値:なし
function script:Main($longside,$originalFileName,$overwrite){
  $private:sourceImage = $null
  $private:resizedImage = $null

  try{
      # 元画像取得(Bitmap)
      $sourceImage = New-Object System.Drawing.Bitmap($originalFileName)

      # 短辺ピクセルを計算
      $private:shortside = CalcSize $sourceImage $longside

      $private:newWidth
      $private:NewHeight

      # 修正後ピクセルを設定
      if($sourceImage.Width -ge $sourceImage.Height){
        $newWidth = $longside
        $newHeight = $shortside
      }else{
        $newWidth = $shortside
        $newHeight = $longside
      }      

      # 新画像Bitmap作成   
      $private:newBitmap = New-Object System.Drawing.Bitmap($sourceImage,$newWidth,$newHeight)
      $private:newGraphics = [System.Drawing.Graphics]::FromImage($newBitmap)

      # 補間方式設定(デフォルト)
      $newGraphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::Default

      # リサイズ
      $newGraphics.DrawImage($sourceImage, 0, 0, $newWidth, $newHeight)
      
      # 上書き時の書き込みロック防止のため元Bitmapを閉じる
      $sourceImage.Dispose()
      
      if($overwrite -eq "n"){
        # 新ファイルネーム
        $private:newFileName = GetNewFileName $originalFileName $longside

        # 保存
        $newBitmap.Save($newFileName, [System.Drawing.Imaging.ImageFormat]::Jpeg)
      
        echo "保存完了しました:$newFileName"
      }else{
      
        # 保存
        $newBitmap.Save($originalFileName, [System.Drawing.Imaging.ImageFormat]::Jpeg)

        echo "保存完了しました:$originalFileName"
      }

  }catch{
    echo "例外が発生しました:$error"
  }finally{
    try{
      # 後始末
      if($null -ne $resizedImage){
        $resizedImage.Dispose()
      }
      if($null -ne $sourceImage){
        $sourceImage.Dispose()
      }
    }catch{
      echo "画像クローズ時の例外:$error"
    }
  }
}

# リサイズ処理の実行
Main $longside $filename $overwrite