クリップボードの画像をJPEG保存&リサイズするPowerShellスクリプト

# モチベーション
スクリーンショットをそのままQiitaの編集画面にペーストするとPNG画像でアップロードされる。
Qiita Teamのファイルアップロード容量には限界が小さいので、なるべくスクリーンショットはJPEGで低画質にしてアップロードしたい。
画像編集ソフトを立ち上げてリサイズしてたがいい加減面倒なので、スクリプトを作った。

# 仕様
- クリップボードの画像を取り込む
 - SnipingTool等のキャプチャツールの連携考慮

- 画像を自動縮小
 - アスペクト比固定 　 
 - 長辺の最大長を指定(指定値に満たないものは縮小せず)

- JPEG画像
 - 品質を指定し、容量削減

- 保存後のファイルをクリップボードに格納
 - Qiitaに投稿する際、そのままCtrl+Cでアップロードできる

# スクリプト
先人の[PowerShellスクリプト](https://qiita.com/saggie/items/44cb8b317fe0effa5891)を改変し、作成した。

<details>
  <summary> ソースコードはこちら</summary><div>

``` powershell:clipboard2temp.ps1
# JPEG品質(longで指定)
$JPEG_QLT = 80L

# 画像の長辺(px)
$LONGSIDE_MAX = 640

Add-Type -AssemblyName System.Windows.Forms
# クリップボードよりBMP画像取得
$clipboardImage = [Windows.Forms.Clipboard]::GetImage()
if ($clipboardImage -ne $null)
{
  # JPEGコーデックを探してくる
  $codecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()|where {$_.MimeType -eq 'image/jpeg'}
  
  # JPEGコーデックの品質を設定する
  $parameters = New-Object System.Drawing.Imaging.EncoderParameters(1)
  $encoder=[System.Drawing.Imaging.Encoder]::Quality
  $parameters.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($encoder, $JPEG_QLT);
  
  # リサイズ -> 長辺を指定px以下にする
  $scale = 1.0
  if($clipboardImage.Width -gt $clipboardImage.Height)
  {
    $scale = [float]$LONGSIDE_MAX / $clipboardImage.Width
  }
  else
  {
    $scale = [float]$LONGSIDE_MAX / $clipboardImage.Height
  }

  if($scale -gt 1.0){ $scale = 1.0 }

  # 縮小先のオブジェクトを生成
  $canvas = New-Object System.Drawing.Bitmap([int]($clipboardImage.Width * $scale), [int]($clipboardImage.Height * $scale))

  # 縮小先へ描画
  $graphics = [System.Drawing.Graphics]::FromImage($canvas)
  $graphics.DrawImage($clipboardImage, (New-Object System.Drawing.Rectangle(0, 0, $canvas.Width, $canvas.Height)))

  # "AppData\Local\Temp"のTEMPフォルダに"clip.jpg"という名前で画像を保存
  $outputFilePath = Join-Path $env:TEMP "clip.jpg"
  $canvas.Save($outputFilePath, $codecInfo, $parameters)

  $filelist = New-Object System.Collections.Specialized.StringCollection
  $filelist.Add($outputFilePath)
  [Windows.Forms.Clipboard]::SetFileDropList($filelist)
  echo "Save to $filelist"
}
else
{
　# 画像データがないよ
  echo "Clipboard contains no image data."
}

Start-Sleep -m 2000 
```

</div>
</details>
.Netの機能をPowerShellから簡単に呼び出せるので、とても実装が簡単でした。

# 使い方

PowerShellのスクリプトファイルは、そのままだと実行するプログラムが関連付けられていない。
右クリックでPowerShellを実行と毎回選択してもいいが、手間なので規定のプログラムを設定する。

まず、PowerShellの実行ファイルのパスを`where powershell`を実行し、確認する。
あらかた、`C:\Windows\System32\WindowsPowerShell\v1.0\`にあるかと思う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61036/58fa5ce5-ab75-a4e7-6638-df84b145b469.png)

つづいて、スクリプトを適当な所に配置する。
今回はとりあえずデスクトップに置いた。

ファイルを右クリックし、「プログラムから開く」 -> 「別のプログラムを選択」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61036/e553d2fb-2e0b-9f00-1766-3ec68263b113.png)

「その他のアプリ↓」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61036/4a2de11f-8498-2e19-0113-2f13d0b559fb.png)

「常にこのアプリを使って.ps1ファイルを開く」にチェックを入れてから、「このPCで別のアプリを探す」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61036/25e2f38f-5a2e-d523-f158-45dd673d20e6.png)

`where powershell`で出てきたパスに移動して、「powershell.exe」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61036/a4a99152-0f1b-0442-5176-395579920a5c.png)

これでファイルをダブルクリックすればツールが実行されるようになった。
あとはSnippingToolやPringScreenキーで画面キャプチャした後、このスクリプトを実行すると、画像が'Temp'フォルダに保存される。
クリップボードに保存ファイルが格納されているので、Qiitaに貼り付けるならそのままCtrl+Vで良し。
ファイルで保存したいなら、デスクトップやエクスプローラでCtrl+Vすれば良し。

縮小する解像度やJPEGの品質をカスタムしたいなら、先程の編集画面からスクリプトの先頭2行を書き換えればよい。

# 参考文献

https://qiita.com/saggie/items/44cb8b317fe0effa5891

https://www.it-mure.jp.net/ja/c%23/imagesave%EF%BC%88%EF%BC%89%E3%81%AFjpeg%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E3%81%A9%E3%81%AE%E5%93%81%E8%B3%AA%E3%83%AC%E3%83%99%E3%83%AB%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/970640009/amp/

http://pc-diary.com/blog/2018/10/windows_powershell.html