PowerShell画像ファイルを読み込み別の場所に保存する。

powershell コンピュータ
powershell

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を使い始めて大分時間が経過しましたが、未だにパイプラインの処理がこれでよいのか不安です。

コメント