PowerShell

【Windowsで簡単変換】PowerShellでHEICをJPGに一括変換するスクリプトを作ったので紹介します

2025年12月3日

PowerShellでHEICをJPGに一括変換するスクリプトのアイキャッチ

はじめに

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: 既存ファイルがある場合は SKIP
  • true : 強制的に上書き

初めて使うときは 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 ポケットリファレンス商品画像

【改訂新版】 Windows PowerShell ポケットリファレンス

PowerShell コマンドを “必要なときにすぐ引ける” 実用リファレンス。
日常の管理作業から自動化まで、ポイントを押さえたコンパクトな解説が魅力。
手元に置いておくとスクリプト作成のスピードが一気に上がります。

おすすめポイント:

  • コマンドや構文がサッと探せて実務で便利
  • 細かい機能やオプションまで網羅されている
  • スクリプト作成中の「詰まり」をすぐ解消できる

Rakuten

Amazon

Yahoo!ショッピング

  • この記事を書いた人
  • 最新記事

かじ

くまyyの管理人:かじ。 社内SEとして13年勤務、システム企画・開発をしているIT屋さん。 ガジェット好きなので最新ガジェットを追いかけるのが好き。 プログラミングなど自分の知識と経験をいろんな人に役立ってもらえるように記事を更新します!

-PowerShell
-,