sironekotoroの日記

Perl で楽をしたい

Perl入学式 2021 始まります! & Perl で 画像を自動トリミングする

Perl 入学式 2021 始まります!

前回更新が 4 月 2 日だったので、3 週間ぶりくらいですか。おひさしぶりです。

ブログも書かずに何をしていたかというと、2021 年度 Perl 入学式の準備をしておりました。

4 月 24 日です!

perl-entrance.connpass.com

2021 年度は、2019 年度までのように手元の PC に Perl をインストールして学習する方法をとります。

macOS ユーザであれば、そのままシステムにインストールされている Perl を利用して学習を進めます。

Windows ユーザの方は以下の動画リストとマニュアルを参考にインストールを行ってください。

github.com

www.youtube.com

うまくいかない場合などには、Perl 入学式の Discord で質問を受けます。活用ください。

Discord の招待リンクです

皆様の参加をお待ちしております!

Perl で画像を自動トリミングしたい

以下のような画像を大量にトリミングする必要が出てきました。これは 1920 x 932 のサイズの画像です。

f:id:sironekotoro:20210420192254p:plain

この、真っ白い部分だけを別のファイルにして抜き出したい!という要望です。要望を出したのは自分ですが・・・

1. 素直に画像ソフトを使って抜き出す

フリーで利用できる GIMP という画像編集ソフトがあります。

www.gimp.org

何冊か本も出ており、うちも下の本を手元に置いています。

GIMP を利用して 1 枚 1 枚心を込めて画像を抜き出していくのも一つの方法です。

が、ちょっと自分には辛い・・・今回だけで 200 枚以上処理する必要あるし。

BIMP というソフトを利用することで 一連の処理をバッチ処理のようにつなげることもできます。

バッチ処理といえば、macOS に入っている Autometer と プレビューの組み合わせでもいけるのかな・・・(思いつき

が、ここはせっかくなので Perl でやってみます。

2. Perl + ImageMagick

Perl で画像を扱う、というかプログラムから画像を扱うときには ImageMagick というソフトを使うのが定番とされていました。

imagemagick.org

が、この ImageMagick は多機能であるが故にインストールが大変なソフトとしても知られています。

うちも何回か挫折しています。

最近だったら Docker や、macOS であれば homebrew 使って入れるのがいいかも知れません。

また、手元で動かすにはいいのですが、世界に公開するサービスに組み込む際には脆弱性に気をつける必要があります。以下は報告されている脆弱性のリストです。

jvndb.jvn.jp

とにかく、 ImageMagick さえ安定して入っていれば、 Perl から ImageMagick を扱うモジュールを通して操作することができます。

しかし今回はこれを使わずにやります。

3. Perl + Imager

インストール&動作確認テスト的なやつ

Perl の画像処理モジュールに Imager というのがあります。これを使います。

metacpan.org

いつものように cpanm Imager でインストール。

SYNOPSYS みて、ふむふむって感じで自分で試してみます。お手軽そうな画像のサイズ縮小をやってみます。

さっきの画像と同じ場所にスクリプト置いて実行します・・・

あっさり成功しました。縦横のサイズが半分になってます。

input.png : 1920x932
output.png : 960x466

ピクセルを指定して切り抜き

では本題。

GIMP で画像を拡大して拡大してルーラーで計ったところ、横(x軸)の白い部分は 631 ピクセルから 1289 ピクセル目までということがわかりました。

縦(y軸)は 932 ピクセルでフルに利用しています。

この情報をもとに抜き出してみます。

こちらもあっさり成功です。きれいに白い所が抜きだせたようです。速度も 1 枚 0.2 秒ほどで申し分なし。

input.png : 1920x932
output_imager_manually_crop.png : 658x932

自動で切り抜き( Imager::Trim

さて、ここでやっぱり楽をしたいなーってなります。

いちいち、画像の部分だけピクセルを測るのが面倒だ、と。このような「よくある要望」は実装されていることが多いです。

実際、Imager::Trim というのがあるんですが、当初うちの環境ではうまく動きませんでした・・・

しかし、このブログを書くにあたって色々検証した結果、fuzz の値を調整し、背景色の情報 color の引数をちゃんと渡すことで警告なしで動くことが判明しました。

# 動く
my $color_cropped_img = $cropped_img->trim( fuzz => 7, color => $color );

# エラーは出るが動く
my $color_cropped_img = $cropped_img->trim( fuzz => 7 );

# エラーは出ないが、切り抜きは失敗する
my $color_cropped_img = $cropped_img->trim( fuzz => 6, color => $color );

ただし遅い。1 枚 10 秒くらいかかります。

input.png : 1920x932
    trim_top:0
    trim_bottom:932
    trim_left:631
    trim_right:1289
output_imger_trim.png : 658x932

自動で切り抜き( Imager::Filter::Autocrop

他のモジュールを探したところ Imager::Filter::Autocrop を見つけました。

こちらは 1 枚 3 秒ほど。この方法を取ることにしました。

input.png : 1920x932
output_imager_filter_autocrop.png : 658x932

md5 で雑に確認してみましたが、どのファイルも同じバイナリのようです。

$ md5 output*
md5: output: Is a directory
MD5 (output_imager_filter_autocrop.png) = ab744b9263aada986381630da980b1f9
MD5 (output_imager_manually_crop.png) = ab744b9263aada986381630da980b1f9
MD5 (output_imager_trim.png) = ab744b9263aada986381630da980b1f9

ということで、画像の抜き出しをやってみた記事でした。

困ったら情報を整理して聞いてみよう!

誰かに聞くつもりで内容をまとめると、そこで気づきが出て解決につながっちゃうというね。

ちなみに、解決しなかったら Perl 入学式の Discord で聞くつもりでおりました。