メモ:PowerShellで画像をリサイズする

PowerShellを使って画像ファイルを縮小保存する方法のメモ

Bitmap クラス (System.Drawing)

として画像を取り込んだ後、

Bitmap コンストラクター (Image, Int32, Int32) (System.Drawing)

で新しい大きさで画像を作成して保存する。

実際のコード

処理上の決め打ちとして、縦横それぞれ半分($Scale = 0.5)にして「マイピクチャ」にJpegで保存している。

Add-Type -AssemblyName System.Drawing

<#
.Synopsis
画像をリサイズしてマイピクチャにJpegで保存する
#>

# 元の画像ファイル
[string]$Path = "C:\hoge.png"

# 変換サイズ
[double]$Scale = 0.5

# 保存形式
[Drawing.Imaging.ImageFormat]$OutFormat = [Drawing.Imaging.ImageFormat]::Jpeg


# ファイルから画像を読み込み([Drawing.Image]の方が良いけど手抜き)
[Drawing.Bitmap]$srcBmp = [Drawing.Bitmap]::FromFile( $Path )

# 新しい画像サイズ
[int]$newWidth  = $srcBmp.Width  * $Scale
[int]$newHeight = $srcBmp.Height * $Scale

# リサイズした画像
[Drawing.Bitmap]$destBmp = 
    New-Object -TypeName Drawing.Bitmap -ArgumentList $srcBmp, $newWidth, $newHeight

# 出力先のパス
[string]$destPath = 
    [IO.Path]::Combine(
        # 親フォルダ
        [Environment]::GetFolderPath([Environment+SpecialFolder]::MyPictures), 
        
        # 拡張子変更
        [IO.Path]::ChangeExtension(
            [IO.Path]::GetFileName($Path), 
            $OutFormat.ToString()
        )   
    )

# 形式指定で保存(既存ファイル上書き)
$destBmp.Save($destPath, $OutFormat)

# 結果確認
Write-Host 保存先は「 $destPath 」です。

上記コードはPowerShellの特徴であるパイプや自動型変換を使うと、以下のようにも書ける。

Add-Type -AssemblyName System.Drawing

<#
.Synopsis
画像をリサイズしてマイピクチャにJpegで保存する
#>

# 元の画像ファイル
$Path = "C:\hoge.png"

# 変換サイズ
$Scale = 0.5

# 保存形式
$OutFormat = "Jpeg"

$Path | %{
        ([Drawing.Bitmap]$_ | 
                %{New-Object -TypeName Drawing.Bitmap -ArgumentList $_, ([int]($_.Width * $Scale)), ([int]($_.Height * $Scale))}
            ).Save([IO.Path]::Combine(
                [Environment]::GetFolderPath("MyPictures"),
                [IO.Path]::ChangeExtension([IO.Path]::GetFileName($_), $OutFormat)   
            ), $OutFormat)
    }

D&Dでつかるようにする

前項のコードは動作確認にはいいけれど、実際には使いにくいのでドラッグ&ドロップで実行できるようにしてみる。

PowerShellのファイルは通常ドロップを受け付けないため、起動用のバッチファイルと本体のスクリプトの2ファイルを用意する。

PowerShell

以下のコードをps1ファイルとして保存する(文字コードを考えるとPowerShell ISEなど経由で保存の方が良いかも)

<#
.Synopsis
画像をリサイズしてマイピクチャにJpegで保存する
#>

if($args.Length -eq 0) {
    explorer.exe ([Environment]::GetFolderPath("SendTo"))
    exit
}

[string[]]$Path = $args

Add-Type -AssemblyName System.Drawing

# 変換サイズ
[double]$Scale = 0.5
# 保存形式
[Drawing.Imaging.ImageFormat]$OutFormat = [Drawing.Imaging.ImageFormat]::Jpeg

Set-StrictMode -Version Latest
$Path | %{
        ([Drawing.Bitmap]$_ | 
                %{New-Object -TypeName Drawing.Bitmap -ArgumentList $_, ([int]($_.Width * $Scale)), ([int]($_.Height * $Scale))}
            ).Save([IO.Path]::Combine(
                [Environment]::GetFolderPath("MyPictures"),
                [IO.Path]::ChangeExtension([IO.Path]::GetFileName($_), $OutFormat)   
            ), $OutFormat)
    }
explorer.exe ([Environment]::GetFolderPath("MyPictures"))

バッチ

上記ps1ファイルと同じ場所、同じ名前で以下のbatファイルを作成する。

@Powershell -ExecutionPolicy RemoteSigned -File "%~dpn0.ps1" %*

あとはbatファイルに画像ファイルをドロップすればファイルが変換される。

ただし、PowerShellの起動時間が1秒ぐらいかかるので、ちゃっちゃとやりたい場合はC#とかで作ってください。