0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pngThrink.ps1

Posted at

1. スクリプト概要

スクリプト名: pngThrink.ps1
pngファイルの最適化を一括で行うスクリプトです

2. 処理と目的

処理の流れ
 1. PNGファイルを検索する対象フォルダのフルパスを入力します
 2. 対象フォルダ内のPNGファイルを検索します
 3. 一時フォルダにPNGファイルをコピーします
 4. OptiPNGで最適化します
 5. OxiPNGで最適化します
 6. PNGOutで最適化します
 7. 最適化が完了したPNGファイルを元ファイルに上書きコピーします
 8. 手順3~7を対象フォルダ内のPNGファイルの数だけ繰り返します

目的
 PNGファイルのサイズを縮小することで、ストレージの容量を節約します

3. 動作環境と要件

PowerShellのバージョン
7.0以上

OS
Windows10

必要なモジュール

  • OptiPNG
  • OxiPNG
  • PNGOut

必要な権限
特になし

その他の設定
特になし

4. 使用方法

基本的な実行方法
スクリプトコードを拡張子ps1で保存してPowershellで実行してください。
ファイルを保存する際は、文字コードをUTF8 BOM付にしてください。
OptiPNG、OxiPNG、PNGOutをそれぞれインストールし、スクリプト内の実行ファイルのパスを適切に修正してください

パラメータ
なし

使用例

  1. コマンドラインでpwsh pngThrink.ps1を実行
  2. 検索対象フォルダを聞いてくるのでフォルダのフルパスを入力

5. スクリプトコード

# ウィンドウのタイトルをスクリプト名に設定
$host.UI.RawUI.WindowTitle = ([IO.Path]::GetFilenameWithoutExtension($PSCommandPath))
# エラー発生時にスクリプトの実行を停止するよう設定
$ErrorActionPreference = 'Stop'

# 各最適化ツールの実行ファイルパスを設定
# ★★★ ここを環境に合わせて修正してください ★★★
$pngout = "D:\png\pngout\pngout.exe"
$optipng = "D:\png\optipng\optipng.exe"
$oxipng = "D:\png\oxipng\oxipng.exe"

# 各ツール実行ファイルの存在チェック
foreach($exepath in @($pngout, $optipng, $oxipng)){
    if (-not(Test-Path -literal $exepath)){
        Write-Warning "最適化プログラム「${exepath}」が見つかりません。スクリプトを終了します。"
        pause
        return
    }
}

# スクリプトの概要と使用方法をコンソールに表示
Write-Host "----------------------------------------------------------------"
Write-Host "対象フォルダ内のPNGファイルをOptiPNG, OxiPNG, PNGOutで最適化し、上書き保存します。" -ForegroundColor White -BackGroundColor Black
Write-Host "複数のフォルダを指定可能です。追加しない場合は何も入力せずEnterを押してください。" -ForegroundColor White -BackGroundColor Black
Write-Host "----------------------------------------------------------------"

# 各最適化ツールの有効/無効フラグ (現状は全て有効)
$enableOptipng = $true
$enablePngout = $true
$enableOxipng = $true

# 最適化対象のPNGファイルパスと検索対象フォルダを格納するリストを初期化
$pngList = New-Object System.Collections.ArrayList
$dirList = New-Object System.Collections.ArrayList

# ユーザーからの検索対象フォルダの入力を繰り返し受け付ける
do {
    $dirname = Read-Host "検索対象フォルダ"
    # 入力が空の場合
    if([String]::IsNullOrEmpty($dirname)){
        # 既にPNGファイルが追加されている場合はループを抜ける
        if($pngList.Count -gt 0){
            break
        }
    }
    # 入力されたパスの前後の引用符を削除
    $dirname = $dirname.Trim('"')
    # 入力されたパスがディレクトリとして存在するかチェック
    if([IO.Directory]::Exists($dirname)){
        # 指定されたディレクトリ内の全てのPNGファイルを再帰的に検索
        $files = [IO.Directory]::GetFiles($dirname, '*.png', [System.IO.SearchOption]::AllDirectories)
        # 検索されたPNGファイルをリストに追加
        $null = $pngList.AddRange($files)
        # 検索対象フォルダをリストに追加
        $null = $dirList.Add($dirname)
        echo "$($files.Count)個のPNGファイルを追加しました。"
    } else {
        Write-Warning "フォルダ「${dirname}」が存在しません!"
    }
} while( $true ) # 無限ループ (breakで抜ける)

# 処理内容の最終確認
Write-Host "フォルダ   :$($dirList -join "`n       :")" -ForegroundColor Cyan
Write-Host "PNG ファイル数:$($pngList.Count)" -ForegroundColor Cyan
Write-Host "OptiPNG 有効化:${enableOptipng}" -ForegroundColor Cyan
Write-Host "OxiPNG 有効化  :${enableOxipng}" -ForegroundColor Cyan
Write-Host "PNGOut 有効化  :${enablePngout}" -ForegroundColor Cyan
Write-Host "上記の内容で最適化処理を開始します。"
pause # ユーザーにEnterキーを押すよう促す

# 最適化処理の進捗カウンターを初期化
$optimizedCount = 0
# 各PNGファイルに対して最適化処理を実行
foreach( $fileFullpath in $pngList ){
    $optimizedCount += 1 # 進捗カウンターをインクリメント

    # 進捗率を計算し、ウィンドウタイトルに表示
    $percent = $optimizedCount * 100 / $pngList.Count
    $filedata = gi -LiteralPath $fileFullpath
    $Host.UI.RawUI.WindowTitle = "PNG Optimize $($percent.ToString('0.#'))% ($($optimizedCount)/$($pngList.Count))"
    echo "$($filedata.fullname) 処理開始..."

    # 一時ファイル名をランダムに生成(既存ファイル名との重複を避ける)
    do {
        $tempfilename = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName() + ".png")
    } while(Test-Path -LiteralPath $tempfilename)

    # 元ファイルを一時フォルダにコピー
    echo "コピー中: $($filedata.Name)$($tempfilename)"
    [IO.File]::Copy($filedata.fullname, $tempfilename)

    # OptiPNGでの最適化
    if( $enableOptipng ){
        echo "OptiPNGで最適化中..."
        & $optipng '-o7' $tempfilename
    }
    # OxiPNGでの最適化
    if( $enableOxipng ){
        echo "OxiPNGで最適化中..."
        & $oxipng $tempfilename |%{ Write-Host $_ -ForegroundColor Cyan}
    }
    # PNGOutでの最適化
    if( $enablePngout ){
        echo "PNGOutで最適化中..."
        & $pngout $tempfilename '/y' '/d0' '/s0' '/mincodes0'
    }

    # 最適化された一時ファイルを元の場所へ上書き移動
    echo "上書き中: $($tempfilename)$($filedata.Name)"
    move -LiteralPath $tempfilename -Destination $filedata.fullname -Force
}
pause

6. 注意事項と既知の問題

制約事項
大量のファイルやサイズの大きいファイルを処理する場合、完了までに時間がかかる可能性があります。

既知のバグ
もしバグを発見された場合は、コメントでご報告ください。

トラブルシューティング
・ps1ファイルのエンコーディングには注意してください。
・OptiPNG、OxiPNG、PNGOutをインストールし、スクリプト内の実行ファイルのパスを適切に修正しないと動作しません。

7. 免責事項

本スクリプトにはいかなる保証もありません。使用は自己責任で行ってください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?