適材適所

PowerShellやVBAなどプログラミング系の話多めで

【PowerShell】大量の画像ファイルのファイル形式(png,jpgなど)を一括で変換する

前回の記事(【PowerShell】ウェブの画像を一括ダウンロードする【スクレイピング】 - 適材適所)で画像を大量にダウンロードしたわけですが、それらの画像の拡張子がpngじゃなくてbmpの方がどうしても都合がよかったんです。

でもそんな大量の画像の拡張子を手作業で変更するのは大変だし、嫌です。 またもやPowerShellを使ってpng形式の画像をbmp形式に変換します。

というわけで、PowerShellを使った画像ファイルの形式を一括で変更する方法の紹介です。

1つの画像ファイルだけならペイントでもいけるよ

1つの画像ファイルの形式を変換するなら簡単。

PowerShellで次のようにすれば簡単にペイントが起動できます。

 
mspaint

あとは画像ファイルをペイントにドラッグアンドドロップして、保存するときに好きな形式を指定してあげれば完了!!

f:id:shinmai_papa:20210911212912p:plain

変換したい画像ファイルが1つだけだったらこれが一番手っ取り早いですが、今回のように大量の画像ファイルを処理するのは大変です。

PowerShellで.netのSystem.Drawingのお力を借りる

System.DrawingクラスのSaveメソッドを使うことで簡単にファイル形式を変更することができます。

まずは対象ファイルが1つだけの場合。pngからbmpへ変換してみます。

 
Add-Type -AssemblyName System.Drawing
#対象の画像を読み込む
$img =[System.Drawing.Image]::FromFile('C:\Users\user\desktop\logo.png')
#任意の形式で保存する
$img.Save("C:\Users\user\desktop\logo.bmp", [System.Drawing.Imaging.ImageFormat]::Bmp)

これを応用すれば、大量の画像ファイルの形式を簡単に変換することができます。

この例ではpngからbmp形式に変換しています。

 
Add-Type -AssemblyName System.Drawing
Get-ChildItem -Path 'C:\Users\USER\Desktop\*.png'|
foreach{$img =[System.Drawing.Image]::FromFile($_.fullname);
$img.Save($(-join((join-path $_.DirectoryName $_.BaseName),".bmp")),[System.Drawing.Imaging.ImageFormat]::Bmp)}

ワンライナーで書いてしまいましたが、一部わかりにくい箇所があるので補足です。

Get-ChildItem -Path 'C:\Users\USER\Desktop\*.png'

この部分、任意のパスになりますが、拡張子は変換したいファイルの拡張子にしてください。ワイルドカード(*)を使っているのでこの例ではすべてのpngファイルが対象になります。

$img.Save($(-join((join-path $_.DirectoryName $_.BaseName),".bmp")),[System.Drawing.Imaging.ImageFormat]::Bmp)

ここの、$imgSaveの第一引数のところが少しややこしいですが、ここでやりたいのは保存先のディレクトリ+拡張子を抜いた元のファイル名+.bmpという文字列を作成することです。

-join(〇〇,△△,・・)と書くことでカッコ内の文字列を結合することができます。まずJoin-Pathコマンドレットで親ディレクトリとBaseName(C:\画像1.pngだったら「画像1」がBaseName)を間違いなく結合します。

Join-Pathは2つの文字列を結合してパス名を作ってくれますが、その際にディレクトリの区切り記号をよしなに処理してくれます。文字列を単純に結合するだけでもいいですが、Join-Pathコマンドレットを使うことでより正確にパス名を生成することができます。

そして、最後に返還後の拡張子である.bmpを結合して、最終的に保存先のフルパスを生成しています。

ここも、".bmp"と[System.Drawing.Imaging.ImageFormat]::Bmpを変換後の拡張子に書き換えてくださいね。

変換できる拡張子一覧

変換できるファイル形式はこちら(ImageFormat クラス (System.Drawing.Imaging) | Microsoft Docs)に詳しくありますが、以下の通りです。

形式 概要
Bmp ビットマップ (BMP) イメージ形式
Emf 拡張メタファイル (EMF) イメージ形式
Exif Exif (Exchangeable Image File) 形式
Gif GIF (Graphics Interchange Format) イメージ形式
Guid この ImageFormat オブジェクトを表す Guid 構造体
Icon Windowsアイコンイメージ形式
Jpeg JPEG (Joint Photographic Experts Group) イメージ形式
MemoryBmp メモリ上のビットマップの形式
Png W3C PNG (Portable Network Graphics) イメージ形式
Tiff TIFF (Tagged Image File Format) イメージ形式
Wmf Windows メタファイル (WMF) イメージ形式

終わりに

PowerShellで大量の画像ファイルの形式を一括で変換する方法を紹介しましたが、半分、というか半分以上、.NETですね。

PowerShellの強みの一つは.NETという超強大な機能群である.NETにお手軽にアクセスすることができる点です。

今回のケースに限らず、PowerShellのコマンドレットだけでは実現できないことも、.NETの力を借りれば簡単に解決できることがたくさんあります。

このブログでも引き続き、折に触れて.NETの機能を活用するネタを書いていきたいと思います。

というわけで、ここまでお読みいただき、ありがとうございました。