タイダログ

もっと怠けますか? (y/n)

PowerShell で複数の画像の同じ領域をトリミングする

スクリーンショットをトリミングするとき、複数の画像から同じ領域を切り出すことがあると思います。Excel の画面を何枚も撮って、画面上部のメニューと下部のタスクバーを除いた部分だけ欲しい、というようなことです。

そんなときに役立ちそうなスクリプトPowerShell で書きました。

作業環境

function

このリポジトリの中の Invoke-ImageTrimming です。

taidalog/pista-image - GitHub

緑色の 'Code' ボタンから 'Download ZIP' して、解凍して、フォルダ名を 'pista-image-main' から 'pista-image' に変えて、モジュールをインポートしてください。方法は「powershell module インポート」とかでググったら出ます。

以下の記事で紹介したスクリプトも入っています。

taidalog.hatenablog.com

taidalog.hatenablog.com

同じ箇所をトリミングする

よく消したくなるのではこの辺りではないでしょうか。

  • Windows のタスクバー
  • ブラウザのアドレスバー
  • Office の一番上のアカウント名

タスクバーとアドレスバーは非表示にできますが、Office のアカウント名(赤い部分)はできません。これはトリミングするしかない。PowerShell で楽をしましょう。

f:id:taidalog:20210905002135p:plain
before

$path = 'a path to an image'
Invoke-ImageTrimming -Path $path -Top 43

パイプライン からの入力を受け付けます。

Get-ChildItem -File | Invoke-ImageTrimming -Bottom 43

f:id:taidalog:20210905002648p:plain
after

使い方

トリミング範囲の指定方法は2通りあります。こちらのパリっぽい炭〇郎、パリ治郎で試しましょう。

ひとつ目は、上下左右の端からそれぞれ何ピクセル切るか指定する方法です。CSS の padding のイメージです。必要ない箇所は省いて構いません。

f:id:taidalog:20210904224358p:plain
before

上から 150 ピクセル、下から 150 ピクセル、左から 100 ピクセル、それぞれ切ります。

Get-ChildItem -File | Invoke-ImageTrimming -Top 150 -Left 100 -Bottom 150

f:id:taidalog:20210904224446p:plain
after (padding)

もうひとつは、始点(左上)の座標と、トリミング範囲の幅と高さを指定する方法です。ペイント等のソフトで確認できます。これがこのまま Rectangle 構造体のコンストラクタの引数になります。

Rectangle(Int32, Int32, Int32, Int32)

f:id:taidalog:20210905030717p:plain
ペイント

Get-ChildItem -File | Invoke-ImageTrimming -X 40 -Y 40 -Width 500 -Height 200

f:id:taidalog:20210904231131p:plain
after (rectangle)

仕組み

こちらを参考にしました。ありがとうございました。

dobon.net

指定した領域を切り取って、その切り取った部分を新たなキャンバスに貼り付けて、名前を付けて保存します。

余白をなくす

フランス料理のお皿のように余白たっぷりな画像もこの通り。トレヴィアン。
※ブログの背景と同化してしまうため、黒い枠線をつけています。実際には枠が付いているとトリミングできません。

f:id:taidalog:20210904235142p:plain
before

Get-ChildItem -File | Invoke-ImageTrimming -Blank

f:id:taidalog:20210904235219p:plain
after (blank)

使い方

-Blank パラメータを付けるだけです。

Get-ChildItem -File | Invoke-ImageTrimming -Blank

余白の残し方は調整できます。

$margin = 40
Get-ChildItem -File | Invoke-ImageTrimming -Blank -MarginTop $margin -MarginRight $margin -MarginBottom $margin -MarginLeft $margin

f:id:taidalog:20210904235456p:plain
after (margin 40)

余白を広く取りすぎて元画像の大きさを超えてしまった場合、背景色を補完します。

f:id:taidalog:20210904235951p:plain
before

$margin = 200
Get-ChildItem -File | Invoke-ImageTrimming -Blank -MarginTop $margin -MarginRight $margin -MarginBottom $margin -MarginLeft $margin

f:id:taidalog:20210905000131p:plain
after (margin 200)

仕組み

上下左右の端から各行列のピクセルの 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

王妃曰く

昔の王妃は言いました。「手作業が嫌ならスクリプトを書いたらいいじゃない」。本当かどうか怪しいそうですが。

何にせよこのスクリプトのおかげでトリミングが格段に楽になり、マニュアル作成にかける時間を削減できたのは確かです。

参考

こちらもどうぞ

taidalog.hatenablog.com

taidalog.hatenablog.com

更新履歴