PowerShellで画像ファイルの読み込みと画像ファイルの保存を、おのおの別スクリプトにすることで再利用することが目的。
以下のような感じで使えるようにするのが目標。
PS >Get-ChildItem "./in/*.png" | ./LoadImage.ps1 | ./SaveImage.ps1 -OutDir="./out"
画像ファイルの読み込み
LoadImage.ps1
<#
.SYNOPSIS
画像ファイルを読み込み。
..DESCRIPTION
画像ファイルを読み込みビットマップオブジェクトを返す。
#>
Param(
[string]$Path,
[switch]$Help
)
function LoadImage
{
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline=$true,Mandatory=$true)]
[string[]]
$path
)
begin {}
process
{
foreach ($p in $Path)
{
$fs = [System.IO.FileStream]::new($p, 3)
$bmp = [System.Drawing.Bitmap]::FromStream($fs)
$fs.Dispose()
[PsCustomObject]@{Name=$p; Value=$bmp}
}
}
end {}
}
$args = @($input)
if ($Help -Or ( -Not $Path -And $args.Count -eq 0))
{
Get-Help $PSCommandPath
Exit 1
}
if ($args.Count -gt 0)
{
if ($args[0] -is [System.IO.FileSystemInfo])
{
$args | % { $_.FullName } | LoadImage
}
else
{
$args | LoadImage
}
}
else
{
LoadImage -path $Path
}
画像オブジェクトの保存
SaveImage.ps1
<#
.SYNOPSIS
画像オブジェクトを保存。
..DESCRIPTION
PsCustomObjectでName=パス,Value=ビットマップオブジェクト形式をパイプラインで渡す。
-OutDirを指定すると画像ファイルがOurDirに保存される。
#>
Param(
[string]$OutDir,
[switch]$Help
)
function SaveImage
{
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline=$true,Mandatory=$true)]
[PsCustomObject[]]
$Obj
)
begin {}
process
{
foreach ($p in $Obj)
{
$dstPath = $p.Name
$bmp = $p.Value
# Write-Host $dstPath
$bmp.Save($dstPath, $bmp.RawFormat.Guid)
}
}
end {}
}
$args = @($input)
if ($Help -Or ( -Not $OutDir -And $args.Count -eq 0))
{
Get-Help $PSCommandPath
Exit 1
}
if ($args.Count -gt 0)
{
if ( $OutDir )
{
# OutDirで保存先のパスを書換
foreach ($o in $args)
{
$path = $o.Name
$baseName = Split-Path $path -Leaf
$dstPath = Join-Path $outDir $baseName
$o.Name = $dstPath
}
}
$args | SaveImage
}
SaveImage.ps1はPsCustomObjectのNameに保存先の画像ファイルのパス、Valueにビットマップオブジェクトをセットしパイプラインで渡します。単一ファイルの保存機能も欲しいところですが、複雑になりそうなので省略しました。
画像の一括処理をPowerShellで作成しようと思ったのですが、毎回同じような画像の読み込みと保存処理を書くことに成るので、再利用できるスクリプトを作れないかと試してみました。
とりあえず画像ファイルが出来上がっていたので思った通りの処理が出来ていると思われます。
PowerShellを使い始めて大分時間が経過しましたが、未だにパイプラインの処理がこれでよいのか不安です。
コメント