PowerShellとImageMagickを使ってWebP画像をJPEGに一括変換する方法

# PowerShellとImageMagickを使ってWebP画像をJPEGに一括変換する方法

前回の記事で、Webサイトで使われる画像形式とその特徴をまとめてみました。
せっかくWeb用に画像を作ったものの、Webサイト側がWebPの読み込みに対応していないことによって、WebPからJPEGで変換しないといけないケースがあったので、今回はPowerShellとImageMagickを使って、WebP形式の画像をJPEG形式に一括変換する方法を紹介したいと思います。

https://qiita.com/shioccii/items/6ef999282424c370a0f7

## WebP形式のおさらい

WebP形式はGoogleが開発した画像フォーマットで、高い圧縮率と品質を両立しています。しかし一部の古いソフトウェアやデバイスではサポートされていないことがあります。そこでWebP画像をより汎用性の高いJPEG形式に変換する必要が出てくることがあります。

## ImageMagickについて

### ImageMagickとは

ImageMagickは、画像の作成、編集、変換を行うための強力なオープンソースソフトウェアです。コマンドラインから操作でき、多くの画像フォーマットをサポートしています。

### インストール方法

WindowsでImageMagickをインストールするには、以下のコマンドをPowerShellで実行します：

```powershell
winget install ImageMagick.ImageMagick
```

インストール後はシステムを再起動するか、PowerShellウィンドウを開きなおしてください。

## WebPからJPEGへの変換スクリプトの解説

### スクリプトの概要

このスクリプトは以下の主要な機能を持っています：

1. 指定されたフォルダ内のすべてのWebP画像をJPEG形式に変換
2. 変換後、元のWebPファイルを削除
3. 1週間以上前に作成されたJPEG画像を自動的に削除

### 主要な機能の説明

1. ImageMagickの確認：
   スクリプトは最初に、ImageMagickがインストールされているかを確認します。

2. WebP画像の変換：
   フォルダ内のすべての.webpファイルを検索し、JPEGに変換します。

3. 元ファイルの削除：
   変換後、元のWebPファイルを削除して、ディスク容量を節約します。

4. 古いJPEG画像の削除：
   1週間以上前に作成されたJPEG画像を自動的に削除します。

### コードの詳細解説

```powershell
# ImageMagickの確認
if (!(Get-Command magick -ErrorAction SilentlyContinue)) {
    Write-Host "Error: ImageMagick is not installed or not in the system PATH." -ForegroundColor Red
    # ... (エラーメッセージと終了処理)
}

# WebP画像の変換
$webpFiles = Get-ChildItem -Path $scriptDir -Filter *.webp
foreach ($file in $webpFiles) {
    $fileName = [System.IO.Path]::GetFileNameWithoutExtension($file.FullName)
    $outputPath = Join-Path $scriptDir "$fileName.jpg"
    
    # 変換実行
    try {
        magick convert $file.FullName $outputPath
        # ... (成功メッセージと元ファイル削除)
    }
    catch {
        # ... (エラー処理)
    }
}

# 古いJPEG画像の削除
$oldFiles = Get-ChildItem -Path $scriptDir -Filter *.jpg | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) }
foreach ($file in $oldFiles) {
    try {
        Remove-Item -Path $file.FullName -Force
        # ... (削除成功メッセージ)
    }
    catch {
        # ... (エラー処理)
    }
}
```

### コード本体

```
# ImageMagickがインストールされているか確認
if (!(Get-Command magick -ErrorAction SilentlyContinue)) {
    Write-Host "Error: ImageMagick is not installed or not in the system PATH." -ForegroundColor Red
    Write-Host "Please install ImageMagick and make sure it's added to the system PATH." -ForegroundColor Yellow
    Write-Host "Press any key to exit..."
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    exit
}

# スクリプトのディレクトリを取得
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# ディレクトリ内のすべての.webpファイルを取得
$webpFiles = Get-ChildItem -Path $scriptDir -Filter *.webp

if ($webpFiles.Count -eq 0) {
    Write-Host "No .webp files found in the directory." -ForegroundColor Yellow
}
else {
    foreach ($file in $webpFiles) {
        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($file.FullName)
        $outputPath = Join-Path $scriptDir "$fileName.jpg"
        
        # 同名のファイルが存在する場合、名前を変更
        $counter = 1
        while (Test-Path $outputPath) {
            $outputPath = Join-Path $scriptDir "$fileName`_$counter.jpg"
            $counter++
        }

        # 変換実行
        try {
            magick convert $file.FullName $outputPath
            Write-Host "Converted: $($file.Name) -> $(Split-Path $outputPath -Leaf)" -ForegroundColor Green
            
            # 元のWebPファイルを削除
            Remove-Item -Path $file.FullName -Force
            Write-Host "Deleted original WebP file: $($file.Name)" -ForegroundColor Yellow
        }
        catch {
            Write-Host "Error converting $($file.Name) : $_" -ForegroundColor Red
        }
    }
    Write-Host "Conversion complete. All original WebP files have been deleted." -ForegroundColor Green
}

# 1週間より前に作成されたJPG画像を削除
$oldFiles = Get-ChildItem -Path $scriptDir -Filter *.jpg | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) }

if ($oldFiles.Count -eq 0) {
    Write-Host "No JPG files older than one week found." -ForegroundColor Yellow
}
else {
    foreach ($file in $oldFiles) {
        try {
            Remove-Item -Path $file.FullName -Force
            Write-Host "Deleted old JPG file: $($file.Name)" -ForegroundColor Yellow
        }
        catch {
            Write-Host "Error deleting $($file.Name) : $_" -ForegroundColor Red
        }
    }
    Write-Host "Deletion of old JPG files complete." -ForegroundColor Green
}

Write-Host "Press any key to exit..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
```


## スクリプトの使用方法

### 準備

1. ImageMagickをインストールします。
2. スクリプトを.ps1ファイルとして保存します（例：`WebpToJpgConverter.ps1`）。

### 実行手順

1. 変換したい画像をPowershellスクリプトが保存されているフォルダに保管します
2. PowerShellを開きます（ユーザー権限でOK）
3. スクリプトが保存されているディレクトリに移動します
4. 以下のコマンドを実行します

```powershell
.\WebpToJpgConverter.ps1
```

### 注意点

- スクリプトは、実行されたディレクトリ内のファイルを対象とします
- 元のWebPファイルは削除されるので、必要に応じてバックアップを取ってください
- 1週間以上前のJPEG画像も自動的に削除されます

## スクリプトのカスタマイズ

### パラメータの調整

- 古いファイルを削除する期間を変更するには、`AddDays(-7)`の数値を調整します
- 特定のサブディレクトリのみを対象にしたい場合は、`$scriptDir`の値を変更します

### 機能の追加や変更のヒント

- 変換する画像形式を増やすには、`-Filter *.webp`の部分を変更します。
- 画像のリサイズや品質調整を行いたい場合は、`magick convert`コマンドにオプションを追加します。

## まとめ

もともと、Instagram用の画像をChatGPTなどで作成する場合、WebPの画像で出力されてしまうため、そのままInstagramに投稿できないといった理由からWebP形式の画像をJPEGに一括変換するスクリプトを作成しました。

元画像や変換後の古い画像は自動削除される仕様としていますので、必要に応じてバックアップを取ったものを使用していただくか、画像のコピーを変換用フォルダに保管してそのフォルダをテンポラリ領域として使用するような運用が望ましいと思います。

私自身は、下記のバッチファイルと併用することでもう少しだけ変換作業を効率化していますが、こういったツールをうまく使うことでより作業時間を短縮できるでしょう。

```
@echo off
pushd %~dp0
powershell -ExecutionPolicy bypass -File .\WebpToJpgConverter.ps1
```

それではまた！