khroma in Hatena Blog

主に音ゲーの記録の独り言

動画のリザルト画面をクリップボードにコピーしたらリサイズ・トリミングしてjpeg形式で保存したい

悩み

録画した動画からリザルト画面をクリップボードにコピーして、ペイントソフトでサイズ調整・トリミングをして保存 の工程がクッソ面倒
(OBS Studioで録画、AviUtlで視聴、AzPainter2で画像調整)

 

使用ソフトたち

obsproject.com

spring-fragrance.mints.ne.jp

hp.vector.co.jp

プログラム作るよ

自分用なのでGUIは無しでいいや、batにしようと思ったけどbatではできないみたい。
PowerShellだとできるっぽい。

PowerShellを書くのは初めてなのでいろいろ調べる。

準備

最初は PowerShell の実行ロックがかかっているらしいので解除する

Set-ExecutionPolicy RemoteSigned

確認

Get-ExecutionPolicy

RemoteSigned と出力されたらOK

作った

  • ctrl+C で停止するまで動き続けるようにする
  • スクリプトと同じディレクトリに出力する
  • jpeg形式で保存する
  • 「日付_インクリメント」な感じのファイル名にする
  • リサイズ・トリミングの値は常に同じなので直書き
    • 元画像サイズ: 1920 * 1080
    • 必要があれば変数にしたり設定ファイルを作成したりなど改修する予定
  • ダブルクリックでPowerShell実行ができないので呼び出し用batも作成する

PowerShellのほう (getClipboardImage.ps1)

# 必要なもののインポート
Add-Type -AssemblyName System.Drawing

# カレントディレクトリ
$path = (Get-Location).Path
# 画像ファイル名
$dateTitle = "20240507"
$index = 0

### 残念ポイントを修正した
# dateTitle部分が同じ画像ファイルがあったら最後のindex+1
$fileList = Get-ChildItem -File -Path $path | Where-Object { $_.Name -match $dateTitle }
if ($fileList.Length -gt 0) {
# 最後のファイル名を取得
    $lastFileName = $fileList[-1].Name
# index部分を抽出
    $lastIndex = $lastFileName -replace "${dateTitle}_(\d+)+.jpg","`${1}"
# +1
  $index = [int]([regex]::replace($lastIndex, "(\d+)", { 1 + $args.value }))
}

while(1) { try { # クリップボードの画像を取得 $image = Get-Clipboard -Format Image if($null -eq $image) { continue } # リサイズ用オブジェクトを生成 $canvas = New-Object System.Drawing.Bitmap(1280, 720) # リサイズ先へ描画 $graphics = [System.Drawing.Graphics]::FromImage($canvas) $graphics.DrawImage($image, (New-Object System.Drawing.Rectangle(0, 0, $canvas.Width, $canvas.Height))) # トリミング $rect = New-Object System.Drawing.Rectangle(402, 0, 878, 720); $dstImage = $canvas.Clone($rect, $canvas.PixelFormat) # トリミング画像保存 $strNum = "{0:d3}" -f $index $outputPath = [System.IO.Path]::Combine($path, $dateTitle + "_" + $strNum + ".jpg") $dstImage.Save($outputPath, [System.Drawing.Imaging.ImageFormat]::Jpeg) $index = $index + 1 # オブジェクトの破棄 $graphics.Dispose() $canvas.Dispose() $dstImage.Dispose() $image.Dispose() Set-Clipboard write-host "保存しました: ${dateTitle}_${strNum}.jpg" } catch { write-host "画像変換中にエラーが発生しました。" $error[0] | Out-String } }

batのほう (getClipboardImage.bat)
pause はとりあえずつけただけ

@echo off
setlocal enabledelayedexpansion
cd %~dp0

powershell .\getClipboardImage.ps1
pause

実行

bat起動

AviUtlで「クリップボードにコピー」を選択

保存ログが出力される
5月5日の動画で20240507を設定しているのはミス

リサイズ・トリミングされたファイルが出力される

実装の残念ポイント(修正済み)

  • 同じ名前のファイルがあっても上書きしてしまう
    • 同じ日付を含むファイルが存在する場合、該当するファイル数からインクリメント部分を調整する

参考

PowerShellって何

qiita.com

変数の使い方、カレントディレクトリの取得

cafebreak.hatenablog.com

クリップボードのイメージを取得

zenn.dev

イメージのリサイズ

qiita.com

イメージのトリミング

koyoshi50.com

jpeg形式で保存

qiita.com

try-catchで実装ミスのエラー内容を見る

totech.hateblo.jp

jpeg品質を指定したい場合はこちらがよさそう(今回は採用せず)

qiita.com

正規表現でファイル存在チェック

qiita.com

文字列置換

qiita.com

配列の最後の要素を取得する

blog.powershell-from.jp