PowerShell で簡単な画像処理オブジェクトを作って遊ぶ

# 経緯

先日、「PowerShell で画像の回転、リサイズを行う」として [ブログ](http://1bed.saloon.jp/?p=2223) や [Qiita](http://qiita.com/miyamiya/items/d1a975fb6618d46eda0c) に投稿したのですが、最近 PowerShell が楽しくなってきているので、練習がてら使い道不明な自己満足ライブラリを書いてみました。多分、更新はしないと思いますが＾＾；

イメージ的には、PowerShell で ImageMagick の convert ぽいのを実装する感じです。

実際に試してみると画像がコロコロ動いて楽しいので、PowerShell に興味持つ人増えるといいな。

# 準備

* [GitHub: miyamiya/mypss](https://github.com/miyamiya/mypss) の右にある `Clone or download` をクリックして zip ファイルをダウンロードします。
* **ダウンロードしたライブラリにはセキュリティの観点からブロックが施されていますので** 、ダウンロードした zip ファイルを右クリックしてプロパティを開き、ブロックの解除にチェックを入れて OK ボタンを押します
* zip ファイルを解凍します
* 処理を行う画像ファイルを用意します
  今回は **before.png** という、画像サイズが **400 x 200** の画像ファイルを用意しました
  ![](http://1bed.saloon.jp/wp-content/uploads/2016/08/before.png)

* 下記例ではこれらを **C:\mypss** に保存しているものとして進めます

# PowerShell の起動

まずは、PowerShell を起動しましょう。PowerShell ISE でも構いません。

Windows マーク(メニューボタン？)を右クリックしてファイル名を指定して実行、`powershell` と入力して OK を押すと起動します。

# Get-Draw の読み込み
PowerShell に次のコマンドを打って読み込みます。

```ps1
& ("Get-Draw.ps1 へのフルパス")
```

前述の通り、今回の例では **C:\mypss** に保存してあるので、そのディレクトリに移動してから読み込みを行います。

```ps1
cd C:\mypss
& ('./Get-Draw.ps1')
```

# オブジェクトの作成

画像ファイルを利用してオブジェクトを作成します。

```ps1
$draw = Get-Draw -File "before.png"
```

# 画像を回転させます

例として時計回りに 90 度回転させます。

```ps1
$draw.rotate.Invoke('90')
```

rotate メソッドは 90, 180, 270 の引数で、それぞれの角度を回転させることができ、NONE を渡すことで回転を止める事が可能です。

* rotate メソッドの例

  ```ps1
    # 回転しない
    $draw.rotate.Invoke('NONE')

    # 時計回りに 90 度回転
    $draw.rotate.Invoke('90')

    # 時計回りに 180 度回転
    $draw.rotate.Invoke('180')

    # 時計回りに 270 度回転
    $draw.rotate.Invoke('270')
  ```

# 一旦保存して確認してみます

```ps1
$draw.save.Invoke('after-turn90.png')
```

回転できました

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/after-turn90.png)


# 画像を水平方向に反転させます

```ps1
$draw.flip.Invoke('X')
```

flip メソッドは X で水平方向に反転、 Y で垂直方向に反転、 XY で水平＆垂直方向に反転し、NONE を渡すことで反転を止めることが可能です。

* flip メソッドの例

  ```ps1
    # 反転しない
    $draw.flip.Invoke('NONE')

    # 水平方向に反転
    $draw.flip.Invoke('X')

    # 垂直方向に反転
    $draw.flip.Invoke('Y')

    # 水平方向と垂直方向に反転
    $draw.flip.Invoke('XY')
  ```

# 一旦保存して確認してみます

```ps1
$draw.save.Invoke('after-turn90-flipX.png')
```

反転できました

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/after-turn90-flipX.png)


# リサイズします

今回の画像は 200 x 100 ですが、50 % にリサイズします。

```ps1
$draw.resize.Invoke('50%')
```

resize メソッドは、パーセンテージ指定とピクセル指定が可能です。

* resize メソッドの例

  ```ps1
    # 幅を 640 ピクセル, 高さは幅の割合に合わせて自動調整
    $draw.resize.Invoke(640)

    # 幅は高さの割合に合わせて自動調整、高さを 320 ピクセル
    $draw.resize.Invoke($null, 320)

    # サイズを 40%
    $draw.resize.Invoke("40%")

    # 幅を 150%, 高さを 200%
    $draw.resize.Invoke("150%", "200%")
  ```

# 一旦保存して確認してみます

```ps1
$draw.save.Invoke('after-turn90-flipX-size50per.png')
```

リサイズできました

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/after-turn90-flipX-size50per.png)


# 画像ファイルの形式を変更する

png 形式から gif 形式に変更します。

```ps1
$draw.format.Invoke('gif')
```

引数で取れるのは .NET Framework の ImageFormat クラスで利用可能な、 bmp , emf , exif , gif , ico , jpg , png , tiff , wmf の形式となります。

* [参考: ImageFormat クラス](https://msdn.microsoft.com/ja-jp/library/system.drawing.imaging.imageformat(v=vs.110).aspx)


**※本メソッドを利用しなくても、save メソッドの引数で指定したファイルの拡張子で自動判定されます**


# 一旦保存して確認してみます

```ps1
$draw.save.Invoke('after-turn90-flipX-size50per.gif')
```

gif ファイルができました

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/after-turn90-flipX-size50per.gif)


# イメージを拡大または回転するときのアルゴリズムを変更します

このライブラリではデフォルトで NearestNeighbor(最近傍補間) になっているので、Low(低品質補間) に変更します。

```ps1
$draw.mode.Invoke('Low')
```

引数で取れるのは .NET Framework の InterpolationMode 列挙体で利用可能な、 Bicubic , Bilinear , Default , High , HighQualityBicubic , HighQualityBilinear , Low , NearestNeighbor の方式となります。

* [参考: InterpolationMode 列挙体](https://msdn.microsoft.com/ja-jp/library/system.drawing.drawing2d.interpolationmode%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)


# 一旦保存して確認してみます

```ps1
$draw.save.Invoke('after-turn90-flipX-size50per-modelow.gif')
```

あまり違いが判らない... ですね＞＜

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/after-turn90-flipX-size50per-modelow.gif)


# 応用: 右クリックメニューに入れる

応用は思い浮かばなかったのですが、例えばこういうことができますね。

以前、「[PowerShell のコマンドを右クリックメニューに入れる](http://1bed.saloon.jp/?p=982)」として行ったのと組み合わせるとこういうことができます。

1. regedit を起動する
2. [HKEY_CLASSES_ROOT]-[*]-[shell] を右クリックして [新規]-[キー]を選択
3. キーに任意の名前(ここでは「画像リサイズ幅640」)をつける(右クリックした時のメニュー名になる)
4. 3 で作ったキーを右クリックして [新規]-[キー]を選択、名前を command にする
5. 4 で作ったキー command をクリックして、右のウィンドウにある (規定)をダブルクリックする
6. 文字列の編集ウィンドウが開くので、値のデータに次のコードを入れ、編集ウィンドウを閉じる

   ```ps1
   "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -WindowStyle Hidden -command "({& ('C:\mypss\Get-Draw.ps1'); $draw = Get-Draw -File '%1'; $draw.resize.Invoke(640); $draw.save.Invoke();}).Invoke()"
   ```

6 まで終わったら、画像ファイルを右クリックすると 「画像リサイズ幅640」 と表示されると思います

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/right-click.png)


「画像リサイズ幅640」 を選択すると同じディレクトリに同じファイル名に「(1)」が付いたファイルができていると思います。

![](http://1bed.saloon.jp/wp-content/uploads/2016/08/before1.png)