Bash関数: ImageMagickで楽に画像をトリミングする
Intro
Win + Shift + S
で複数回まったく同じ領域を切り抜くのは難しい……。
そうだ、ImageMagickを使おう!
TL; DR
この記事では、ImageMagickを使って画像をトリミングするBash関数を作成する方法を紹介する。この関数を使うことで、画像の切り抜きの手間を減らすことができる。
ImageMagick
ImageMagickの紹介記事に先んじる形になったので、簡単にその紹介をしておこう。
- ImageMagickは画像編集のためのCUIツール
- 画像のリサイズ、トリミング、合成、変換などが可能
- 画像処理の自動化やバッチ処理に向いている
- コマンドとしては
convert
を用いる (ImageMagick
はいずこへ)
Crop Image with ImageMagick
今回は画像のトリミング(croping)、すなわち切り抜きについて扱う。
多くの場合、cropingは内容に着目して行われるので、GUIツール (たとえばペイントやWin+Shift+S
)が適している。
だが、複数回にわたって同じ座標での切り出しが必要な場合や、切り抜き座標が指定されている場合は、ImageMagickの利用が有用だろう。
実際、pure ImageMagickで画像をcropingしたい場合、以下のコマンドを実行する。
1 |
|
これで、input.jpg
のx
からx+width
、y
からy+height
の範囲を切り抜いてoutput.jpg
として保存することができる。ちなみに原点は左上で、x軸とy軸の正の向きはそれぞれ右と下だ。
下の画像の場合は、x=100
, y=100
, width=200
, height=200
として切り抜いている。
座標読み取り
まずは基準となる座標の読み取りを行う。
なんらかのソフトを経由することになるが、実はWindowsのペイントで事足りる。
カーソルの座標が左下に表示される。
不満点
では、何が不満なのか。
それは、わざわざ引き算を経由する必要があることだ。
先の手順に従えば、切り抜きたい領域の左上と右下の座標がまず取得され、その後に幅と高さを計算する必要がある。具体的には以下の通りだ。
- 左上の座標
(x1, y1)
、右下の座標(x2, y2)
を取得 - 幅
width = x2 - x1
、高さheight = y2 - y1
を計算 - convertにx1, y1, width, heightを渡す
無論、大した計算ではないのだが、ことあるごとに計算するのも面倒である。
そこで、どうせ機械に切り抜き処理させるなら、この引き算の処理も任せてしまおうというわけだ。
解決策: 作成されたScript
1 |
|
今回のScriptの技術的な解説 by ChatGPT
上記Scriptの技術的な解説 by ChatGPT
このBashスクリプトは、画像を指定した範囲で切り抜く(クロップする)ためのツールを提供します。以下に、このスクリプトの各部分をBash未経験者向けにわかりやすく説明します。
スクリプト全体の概要
このスクリプトを使うと、画像ファイルの一部を新しいファイルとして切り抜くことができます。cropImage
というコマンドを使って、元の画像ファイルと切り抜きたい範囲を指定します。例えば、cropImage input.jpg 10 10 100 100
とすると、input.jpg
の(10,10)から(100,100)の範囲を切り抜いた新しい画像ファイルが作成されます。
詳細な説明
1. alias
の設定
1 |
|
- alias (エイリアス):
alias
コマンドを使って、新しいコマンドを定義します。ここでは、cropImage
というコマンドを定義しており、実際には_CropImage
という関数を呼び出します。 - 目的:
cropImage
という簡単な名前で画像を切り抜く関数を呼び出せるようにしています。
2. 関数の定義
1 |
|
- function (関数): 関数は、一連のコマンドをまとめて名前を付けて定義するものです。ここでは、
_CropImage
という関数を定義しています。
3. 入力引数の取得
1 |
|
- 引数: 関数は呼び出すときに引数を受け取ることができます。
$1
,$2
,$3
,$4
,$5
は関数に渡された引数を表します。$1
: 入力ファイル名$2
: 切り抜き範囲の左上のx座標(デフォルトは0)$3
: 切り抜き範囲の左上のy座標(デフォルトは0)$4
: 切り抜き範囲の右下のx座標(デフォルトは1000)$5
: 切り抜き範囲の右下のy座標(デフォルトは1000)
4. 切り抜き範囲の計算
1 |
|
- 計算:
$(())
は算術演算を行うための構文です。ここでは、切り抜き範囲の高さと幅を計算しています。
5. 出力ファイルの名前を生成
1 |
|
- 文字列操作:
${input_file/ /_/}
は、入力ファイル名の中の空白をアンダースコアに置き換えています。これにより、出力ファイル名に空白が含まれないようにします。 - 出力ファイル名:
crop_
を接頭辞として付けた新しいファイル名を生成します。
6. 入力ファイルの存在チェック
1 |
|
- 存在チェック:
[[ ! -f $input_file ]]
は、指定されたファイルが存在しない場合に真となります。 - エラーメッセージ: ファイルが存在しない場合にエラーメッセージを表示し、関数を終了します。
7. 出力ファイルの存在チェック
1 |
|
- 存在チェック:
[[ -f "$output_file" ]]
は、出力ファイルが既に存在する場合に真となります。 - エラーメッセージ: 出力ファイルが既に存在する場合にエラーメッセージを表示し、関数を終了します。
8. 画像の切り抜き
1 |
|
- ImageMagickのconvertコマンド:
convert
はImageMagickという画像処理ライブラリに含まれるコマンドです。このコマンドを使って画像を切り抜きます。"$input_file"
: 入力ファイル-crop ${width}x${height}+${x1}+${y1}
: 切り抜き範囲の指定(幅、高さ、左上のx座標、左上のy座標)"$output_file"
: 出力ファイル
まとめ
このスクリプトは、指定した画像ファイルの一部を切り抜いて新しいファイルとして保存するためのツールです。以下の手順で動作します:
cropImage
というコマンドを定義。- 関数
_CropImage
を呼び出して、画像の切り抜き処理を行う。 - 入力ファイルの存在チェックや出力ファイルの名前生成、切り抜き範囲の計算を行う。
- 最後に
convert
コマンドを使って画像を切り抜く。
このスクリプトを使うことで、簡単に画像の一部を切り抜いて新しいファイルとして保存することができます。
作成の直接のきっかけ
ちなみに、VSCodeのススメ執筆が、直接の作成のきっかけだった。
が、結局採用されていない。正直gifアニメーションの方が明らかに伝わりやすかった。
まあ、このBash関数作成の良い機会になったということで。
切り抜き前後の画像は下記の通り。まったく同じ領域を切り抜けており、比較がきれいにできていることが伝わるだろう。なお、下記の画像比較はスマホで正常に動作しなかった。(そのうち記事にしようと思ってたのに、ケチがついたなぁ)
切り抜き前


切り抜き後


まとめ
今回は、ImageMagickを使って画像をトリミングするBash関数を作成した。
この関数を使うことで、画像切り抜きの手間を減らすことができる。