はじめに
iPhone で撮った写真は標準で HEIC(HEIF)形式になっています。ファイルサイズが小さくて便利なのですが、Windows の古いアプリやブログサービスによっては JPG の方が扱いやすいことがあります。
今回は、Windows に標準で入っている WIC(Windows Imaging Component)を使って HEIC → JPG へ変換する PowerShell スクリプトを作ったのでご紹介します。
- フォルダ内の HEIC をまとめて JPEG 化
- 画質(Quality)を自由に変更できる
- 既存 JPG があれば上書きせずスキップ
動作環境・前提条件
この記事で紹介するスクリプトは、次の環境で動作確認しています。
- Windows 11 Pro / Windows 10
- PowerShell 5.x / PowerShell 7.x
- iPhoneの HEIC を普通に読めるよう、HEIF 画像拡張機能をインストール済み
また、今回利用している WIC(Windows Imaging Component)は Windows 標準機能ですので、追加ソフトは不要です。
※OneDrive などクラウド同期フォルダの場合、「オフラインで利用できる状態」になっていない画像は変換できません。
必要に応じて手動でローカル保存してから実行してください。
スクリプトの全体像(HEIC-to-JPG.ps1)
今回作成したスクリプトがこちらです。
# HEIC-to-JPG.ps1
# 固定フォルダ:入力 C:\data1\Pictures\HEIC / 出力 C:\data1\Pictures\Converted
# WIC(PresentationCore)でHEICをJPEG化。既存ファイルは上書きしません。
$InputFolder = 'C:\data1\Pictures\HEIC'
$OutputFolder = 'C:\data1\Pictures\Converted'
$Quality = 92 # 50~100で調整可
$Overwrite = $false
# 必要アセンブリ(WIC)
Add-Type -AssemblyName PresentationCore | Out-Null
function Convert-HeicToJpeg {
param(
[string]$InPath,
[string]$OutPath,
[int]$Quality,
[bool]$Overwrite
)
try {
$fi = Get-Item -LiteralPath $InPath -ErrorAction Stop
if ($fi.Length -eq 0 -or ($fi.Attributes.ToString() -match 'Offline')) {
throw "File is not fully available locally (OneDrive placeholder or zero-length)."
}
$dir = Split-Path -Path $OutPath -Parent
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }
if ((Test-Path $OutPath) -and -not $Overwrite) {
return "SKIP (exists): $OutPath"
}
# 入力をストリームで読み込み → OnLoad で完全デコードしてクローズ(ロック回避)
$fsIn = [System.IO.File]::Open($InPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read)
try {
$decoder = [System.Windows.Media.Imaging.BitmapDecoder]::Create(
$fsIn,
[System.Windows.Media.Imaging.BitmapCreateOptions]::IgnoreColorProfile,
[System.Windows.Media.Imaging.BitmapCacheOption]::OnLoad
)
} finally {
$fsIn.Dispose()
}
$frame = $decoder.Frames[0]
$encoder = New-Object System.Windows.Media.Imaging.JpegBitmapEncoder
$encoder.QualityLevel = $Quality
$encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($frame))
$fsOut = [System.IO.File]::Open($OutPath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::None)
try {
$encoder.Save($fsOut)
} finally {
$fsOut.Dispose()
}
return "OK: $OutPath"
}
catch {
return "NG: $InPath -> $($_.Exception.Message)"
}
}
# 対象取得(サブフォルダは含めません。必要なら -Recurse を追加)
$files = Get-ChildItem -LiteralPath $InputFolder -Include *.heic, *.heif -File -ErrorAction SilentlyContinue
if (-not $files) {
Write-Host "HEIC/HEIFが見つかりません: $InputFolder"
exit 1
}
Write-Host "変換開始:$($files.Count) ファイル"
$results = foreach ($f in $files) {
$out = Join-Path $OutputFolder ($f.BaseName + ".jpg")
Convert-HeicToJpeg -InPath $f.FullName -OutPath $out -Quality $Quality -Overwrite:$Overwrite
Start-Sleep -Milliseconds 10 # I/Oバースト緩和(任意)
}
# サマリ
$ok = ($results | Where-Object { $_ -like 'OK:*' }).Count
$skip = ($results | Where-Object { $_ -like 'SKIP*' }).Count
$ng = ($results | Where-Object { $_ -like 'NG:*' }).Count
$results | ForEach-Object { Write-Host $_ }
Write-Host "完了:OK=$ok, SKIP=$skip, NG=$ng"
使い方
変換したい HEIC をフォルダに入れる
スクリプトの初期設定では次のフォルダを使います。
- 入力フォルダ:
C:\data1\Pictures\HEIC - 出力フォルダ:
C:\data1\Pictures\Converted
必要に応じて任意のフォルダに変更してください。
スクリプトを実行
HEIC-to-JPG.ps1を任意の場所に保存- PowerShell を開き、スクリプトのあるフォルダへ移動
- 初回のみ実行ポリシーの変更が必要な場合があります
- Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
- 実行
- .\HEIC-to-JPG.ps1
変換結果は PowerShell 上に、こんな感じで出力されます。
変換開始:12 ファイル
OK: D:\data1\Pictures\Converted\IMG_001.jpg
SKIP (exists): ...
NG: ...
完了:OK=11, SKIP=1, NG=0
わかりやすく成功 / スキップ / 失敗が確認できます。
パラメータのカスタマイズ
画質(Quality)
$Quality = 92 # 50~100で調整
- 数値が大きいほど高画質(そのぶんサイズも増えます)
- ブログ用途なら 85〜92 がバランス良い印象です
上書き設定(Overwrite)
$Overwrite = $false
false: 既存ファイルがある場合は SKIPtrue: 強制的に上書き
初めて使うときは false がおすすめです。
スクリプトのポイント(技術解説)
WIC(PresentationCore)で変換
外部ライブラリは不要で、Windows 標準機能のみを利用して HEIC をデコードして JPG を作成しています。
Add-Type -AssemblyName PresentationCore
ファイルロックしない仕組み
画像データを読み込む際、
BitmapCacheOption::OnLoad
を使うことで、
- 読み込み直後にファイルのロックを解除
- 書き込み処理で競合しない
というメリットがあります。
よくあるカスタマイズ例
サブフォルダもすべて変換したい
サブフォルダも含めて変換したい場合は下記のオプションを追加すると変換可能です。
Get-ChildItem -Recurse ...
拡張子を .jpeg にしたい
変換後の拡張子を下記に変更してください。
($f.BaseName + ".jpeg")
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
| 「HEIC/HEIFが見つかりません」 | 入力フォルダが違う | フォルダパスをチェック |
| 「File is not fully available locally」 | OneDrive のプレースホルダ | ファイルをローカル保存 |
| 実行できない | 実行ポリシーの制限 | Set-ExecutionPolicy を設定 |
| 黒い画像になる・読み込めない | HEIF 拡張機能が無効 | Microsoft Store から再インストール |
まとめ
今回は、PowerShell を使って HEIC を JPG へ一括変換するスクリプトを紹介しました。
- Windows 標準の WIC を使うので追加ソフト不要
- フォルダに入れて実行するだけ
- OneDrive や既存ファイルにも配慮
- パラメータを変えればカスタマイズも簡単
HEIC を大量に扱う方や、定期的に変換してブログにアップする人には特におすすめです。

【改訂新版】 Windows PowerShell ポケットリファレンス
PowerShell の基本コマンドから応用スクリプトまで、すぐ動くサンプルで学べる実践書です。
ファイル操作・条件分岐・ループ・エラーハンドリングなど、“実際に手を動かす” ことで理解が進みます。
PowerShell の基礎力と応用力を同時に高めたい人におすすめです。
おすすめポイント:
- 動作するサンプルが豊富で理解が早い
- 自動化に必要な基礎文法〜実践スクリプトを広くカバー
- 初級者から中級者へのステップアップに最適