ダイビング以外のブログ用写真は、オリンパスのTG-4で撮っており、実際に掲載する際には、縦横30%ぐらいにリサイズしている。
リサイズには、Windowsの標準ソフトのペイントを使っているのだが、枚数が多いと結構手間。
そこで、プログラムを使って一括処理をすることにした。
使用するのは、PowerShell。
PowerShell自体、5年ほど前までは結構使っていたのだが、この頃は全く使っておらず、ちょっと忘れ気味。再度いろいろなサイトを参考に作成してみた。
ソースコード
Add-Type -AssemblyName System.Drawing
function ResizeImage($fileName, $size)
{
# 画像ファイルの読みこみ
$fromBmp = [Drawing.Image]::FromFile($fileName)
# リサイズ先のビットマップを作成
# サイズは、$sizeで指定されている倍率にする
$toBmp = New-Object Drawing.Bitmap([int]($fromBmp.Width * $size), [int]($fromBmp.Height * $size))
# 属性の引継ぎ(Exifや回転情報などが引き継がれるはず)
foreach($prop in $fromBmp.PropertyItems) {
$toBmp.SetPropertyItem($prop);
}
# リサイズ先のビットマップでGraphicオブジェクトを作成し、元図形をリサイズ先のビットマップの大きさでコピーする
$graphics = [Drawing.Graphics]::FromImage($toBmp)
$graphics.DrawImage($fromBmp, 0, 0, $toBmp.Width, $toBmp.Height)
# リサイズ後のビットマップを_sというファイル名を付けて保存する
$saveFile = [IO.Path]::Combine([IO.Path]::GetDirectoryName($fileName), [IO.Path]::GetFileNameWithoutExtension($fileName) + "_s" + [IO.Path]::GetExtension($fileName))
$saveFile
$toBmp.Save($saveFile, [Drawing.Imaging.ImageFormat]::Jpeg)
}
# 引数で渡されたファイルに対して 0.3 倍のサイズにする処理を通す
foreach ($filename in $args)
{
$fp = [IO.Path]::GetFullPath($fileName);
ResizeImage $fp 0.3
}
動作内容
引数をファイル名群と認識し、ResizeImage関数にファイル名とリサイズの係数を渡すようにしてある。
ResizeImage関数内では以下のような処理をしている。
- ファイルの中身をロードし、イメージオブジェクトを作成。
- リサイズ先のイメージオブジェクトを作成。
- 元のファイルの属性を、リサイズ先のオブジェクトに設定。
- グラフィックオブジェクトを作成し、オリジナルのイメージをリサイズして、リサイズ先のイメージに複写。
- 保存先名称を作成。
元のファイルに”_s”を付けた形にしている。 - 保存
属性の複写
foreach($prop in $fromBmp.PropertyItems) {
$toBmp.SetPropertyItem($prop);
}
この部分の処理なのだが、PowerShellのイメージ処理のサンプル系にはなかった。
当初、この部分を外したコードで処理したところ、以下のような結果になった。
- オリジナルのファイル
- サイズ変更後のファイル
Exif情報が削除されているのは、しょうがないと感じたのだが、画像の回転情報が抜けてしまっていた。
そのため、変更前は縦撮りしたものが、リサイズ後のファイルは横向きになってしまっていた。
PowerShellのデバッガで見たところ、元ファイルのイメージをロードした後のオブジェクトに、プロパティが追加されていたので、試しに上記のコードを入れたところ、以下のような実行結果となった。
リサイズはされているが、一応Exif情報も引き継いでいる。
コメント