スクリーンショットをトリミングするとき、複数の画像から同じ領域を切り出すことがあると思います。Excel の画面を何枚も撮って、画面上部のメニューと下部のタスクバーを除いた部分だけ欲しい、というようなことです。
そんなときに役立ちそうなスクリプトを PowerShell で書きました。
作業環境
- Windows 10 20H2 (Build 19042.1165)
- Windows PowerShell 5.1.19041.1151
- PowerShell 7.1.3
function
このリポジトリの中の Invoke-ImageTrimming です。
緑色の 'Code' ボタンから 'Download ZIP' して、解凍して、フォルダ名を 'pista-image-main' から 'pista-image' に変えて、モジュールをインポートしてください。方法は「powershell module インポート」とかでググったら出ます。
以下の記事で紹介したスクリプトも入っています。
同じ箇所をトリミングする
よく消したくなるのではこの辺りではないでしょうか。
- Windows のタスクバー
- ブラウザのアドレスバー
- Office の一番上のアカウント名
タスクバーとアドレスバーは非表示にできますが、Office のアカウント名(赤い部分)はできません。これはトリミングするしかない。PowerShell で楽をしましょう。
$path = 'a path to an image' Invoke-ImageTrimming -Path $path -Top 43
パイプライン からの入力を受け付けます。
Get-ChildItem -File | Invoke-ImageTrimming -Bottom 43
使い方
トリミング範囲の指定方法は2通りあります。こちらのパリっぽい炭〇郎、パリ治郎で試しましょう。
ひとつ目は、上下左右の端からそれぞれ何ピクセル切るか指定する方法です。CSS の padding のイメージです。必要ない箇所は省いて構いません。
上から 150 ピクセル、下から 150 ピクセル、左から 100 ピクセル、それぞれ切ります。
Get-ChildItem -File | Invoke-ImageTrimming -Top 150 -Left 100 -Bottom 150
もうひとつは、始点(左上)の座標と、トリミング範囲の幅と高さを指定する方法です。ペイント等のソフトで確認できます。これがこのまま Rectangle 構造体のコンストラクタの引数になります。
Rectangle(Int32, Int32, Int32, Int32)
Get-ChildItem -File | Invoke-ImageTrimming -X 40 -Y 40 -Width 500 -Height 200
仕組み
こちらを参考にしました。ありがとうございました。
指定した領域を切り取って、その切り取った部分を新たなキャンバスに貼り付けて、名前を付けて保存します。
余白をなくす
フランス料理のお皿のように余白たっぷりな画像もこの通り。トレヴィアン。
※ブログの背景と同化してしまうため、黒い枠線をつけています。実際には枠が付いているとトリミングできません。
Get-ChildItem -File | Invoke-ImageTrimming -Blank
使い方
-Blank
パラメータを付けるだけです。
Get-ChildItem -File | Invoke-ImageTrimming -Blank
余白の残し方は調整できます。
$margin = 40 Get-ChildItem -File | Invoke-ImageTrimming -Blank -MarginTop $margin -MarginRight $margin -MarginBottom $margin -MarginLeft $margin
余白を広く取りすぎて元画像の大きさを超えてしまった場合、背景色を補完します。
$margin = 200 Get-ChildItem -File | Invoke-ImageTrimming -Blank -MarginTop $margin -MarginRight $margin -MarginBottom $margin -MarginLeft $margin
仕組み
上下左右の端から各行列のピクセルの ARGB 値をオラオラと見ていって、背景色しかない無駄無駄な行列を取り除いています。元の画像には変更を加えず、新たな画像として保存します。
背景色は指定できますが、しなかった場合は一番左上、つまり座標 (0, 0) のピクセルの色を使用します。透過画像も問題ありません。通常は指定しなくていいと思います。
背景色は ARGB 値で設定しますので、少しでも違う色は背景とはみなしません。ですのでグラデーションがかかった背景等には効果がありません。
背景色の指定には Color 構造体を使います。FromArgb(Int32, Int32, Int32, Int32) メソッドか色の名前で Color 構造体を生成します。
# FromArgb() メソッド $color = [System.Drawing.Color]::FromArgb(255, 1, 36, 86) Get-ChildItem -File | Invoke-ImageTrimming -Blank -Color $color
# 色の名前 $color = [System.Drawing.Color]::AliceBlue Get-ChildItem -File | Invoke-ImageTrimming -Blank -Color $color
王妃曰く
昔の王妃は言いました。「手作業が嫌ならスクリプトを書いたらいいじゃない」。本当かどうか怪しいそうですが。
何にせよこのスクリプトのおかげでトリミングが格段に楽になり、マニュアル作成にかける時間を削減できたのは確かです。
参考
- 画像の一部を切り取って(トリミングして)表示する - .NET Tips (VB.NET,C#...)
- Bitmap Class (System.Drawing) | Microsoft Docs
- Color Struct (System.Drawing) | Microsoft Docs
- Graphics Class (System.Drawing) | Microsoft Docs
- Rectangle Struct (System.Drawing) | Microsoft Docs
- SolidBrush Class (System.Drawing) | Microsoft Docs